OmniSciDB  8a228a1076
org.apache.calcite.sql2rel.SqlToRelConverter Class Reference
+ Collaboration diagram for org.apache.calcite.sql2rel.SqlToRelConverter:

Classes

class  Blackboard
 
class  DeferredLookup
 
class  NoOpSubQueryConverter
 
class  RexAccessShuttle
 

Public Member Functions

 SqlToRelConverter (RelOptTable.ViewExpander viewExpander, SqlValidator validator, Prepare.CatalogReader catalogReader, RelOptPlanner planner, RexBuilder rexBuilder, SqlRexConvertletTable convertletTable)
 
 SqlToRelConverter (RelOptTable.ViewExpander viewExpander, SqlValidator validator, Prepare.CatalogReader catalogReader, RelOptCluster cluster, SqlRexConvertletTable convertletTable)
 
 SqlToRelConverter (RelOptTable.ViewExpander viewExpander, SqlValidator validator, Prepare.CatalogReader catalogReader, RelOptCluster cluster, SqlRexConvertletTable convertletTable, Config config)
 
RelOptCluster getCluster ()
 
RexBuilder getRexBuilder ()
 
int getDynamicParamCount ()
 
RelDataType getDynamicParamType (int index)
 
int getDynamicParamCountInExplain (boolean increment)
 
Map< SqlNode, RexNode > getMapConvertedNonCorrSubqs ()
 
void addConvertedNonCorrSubqs (Map< SqlNode, RexNode > alreadyConvertedNonCorrSubqs)
 
void setSubQueryConverter (SubQueryConverter converter)
 
void setDynamicParamCountInExplain (int explainParamCount)
 
RelNode flattenTypes (RelNode rootRel, boolean restructure)
 
RelNode decorrelate (SqlNode query, RelNode rootRel)
 
RelNode trimUnusedFields (boolean ordered, RelNode rootRel)
 
RelRoot convertQuery (SqlNode query, final boolean needsValidation, final boolean top)
 
RelNode convertSelect (SqlSelect select, boolean top)
 
RelNode convertToSingleValueSubq (SqlNode query, RelNode plan)
 
RexNode convertExpression (SqlNode node)
 
RexNode convertExpression (SqlNode node, Map< String, RexNode > nameToNodeMap)
 
RexDynamicParam convertDynamicParam (final SqlDynamicParam dynamicParam)
 
boolean isTrimUnusedFields ()
 
RelNode toRel (final RelOptTable table, final List< RelHint > hints)
 
RelRoot convertWith (SqlWith with, boolean top)
 
RelNode convertValues (SqlCall values, RelDataType targetRowType)
 

Static Public Member Functions

static boolean isOrdered (SqlNode query)
 

Public Attributes

final SqlToRelConverter.Config config
 
final RelOptTable.ViewExpander viewExpander
 

Static Public Attributes

static final int DEFAULT_IN_SUB_QUERY_THRESHOLD = 20
 
static final int DEFAULT_IN_SUBQUERY_THRESHOLD = DEFAULT_IN_SUB_QUERY_THRESHOLD
 

Protected Member Functions

RelFieldTrimmer newFieldTrimmer ()
 
Blackboard createBlackboard (SqlValidatorScope scope, Map< String, RexNode > nameToNodeMap, boolean top)
 
void convertSelectImpl (final Blackboard bb, SqlSelect select)
 
void convertOrder (SqlSelect select, Blackboard bb, RelCollation collation, List< SqlNode > orderExprList, SqlNode offset, SqlNode fetch)
 
int getInSubqueryThreshold ()
 
RexNode convertExtendedExpression (SqlNode node, Blackboard bb)
 
void convertFrom (Blackboard bb, SqlNode from)
 
void convertFrom (Blackboard bb, SqlNode from, List< String > fieldNames)
 
void convertMatchRecognize (Blackboard bb, SqlCall call)
 
void convertCollectionTable (Blackboard bb, SqlCall call)
 
void afterTableFunction (SqlToRelConverter.Blackboard bb, SqlCall call, LogicalTableFunctionScan callRel)
 
RelNode createJoin (Blackboard bb, RelNode leftRel, RelNode rightRel, RexNode joinCond, JoinRelType joinType)
 
List< RelDataTypeField > getSystemFields ()
 
void convertAgg (Blackboard bb, SqlSelect select, List< SqlNode > orderExprList)
 
final void createAggImpl (Blackboard bb, final AggConverter aggConverter, SqlNodeList selectList, SqlNodeList groupList, SqlNode having, List< SqlNode > orderExprList)
 
RelNode createAggregate (Blackboard bb, ImmutableBitSet groupSet, ImmutableList< ImmutableBitSet > groupSets, List< AggregateCall > aggCalls)
 
void gatherOrderExprs (Blackboard bb, SqlSelect select, SqlNodeList orderList, List< SqlNode > extraOrderExprs, List< RelFieldCollation > collationList)
 
RelFieldCollation convertOrderItem (SqlSelect select, SqlNode orderItem, List< SqlNode > extraExprs, RelFieldCollation.Direction direction, RelFieldCollation.NullDirection nullDirection)
 
boolean enableDecorrelation ()
 
RelNode decorrelateQuery (RelNode rootRel)
 
RelRoot convertQueryRecursive (SqlNode query, boolean top, RelDataType targetRowType)
 
RelNode convertSetOp (SqlCall call)
 
RelNode convertInsert (SqlInsert call)
 
RelOptTable getTargetTable (SqlNode call)
 
RelNode convertColumnList (final SqlInsert call, RelNode source)
 
void collectInsertTargets (SqlInsert call, final RexNode sourceRef, final List< String > targetColumnNames, List< RexNode > columnExprs)
 
RexNode adjustInputRef (Blackboard bb, RexInputRef inputRef)
 
void extraSelectItems (Blackboard bb, SqlSelect select, List< RexNode > exprList, List< String > nameList, Collection< String > aliasList, List< SqlMonotonicity > columnMonotonicityList)
 

Protected Attributes

final SqlValidator validator
 
final RexBuilder rexBuilder
 
final Prepare.CatalogReader catalogReader
 
final RelOptCluster cluster
 
final Map< RelNode, Integer > leaves = new HashMap<>()
 
final RelDataTypeFactory typeFactory
 

Static Protected Attributes

static final Logger SQL2REL_LOGGER = CalciteTrace.getSqlToRelTracer()
 

Private Member Functions

void checkConvertedType (SqlNode query, RelNode result)
 
RelCollation requiredCollation (RelNode r)
 
void distinctify (Blackboard bb, boolean checkForDupExprs)
 
void convertWhere (final Blackboard bb, final SqlNode where)
 
void replaceSubQueries (final Blackboard bb, final SqlNode expr, RelOptUtil.Logic logic)
 
void substituteSubQuery (Blackboard bb, SubQuery subQuery)
 
RexNode translateIn (RelOptUtil.Logic logic, RelNode root, final RexNode rex)
 
boolean convertNonCorrelatedSubQuery (SubQuery subQuery, Blackboard bb, RelNode converted, boolean isExists)
 
RexNode convertInToOr (final Blackboard bb, final List< RexNode > leftKeys, SqlNodeList valuesList, SqlInOperator op)
 
RexNode ensureSqlType (RelDataType type, RexNode node)
 
RelOptUtil.Exists convertExists (SqlNode seek, RelOptUtil.SubQueryType subQueryType, RelOptUtil.Logic logic, boolean notIn, RelDataType targetDataType)
 
RelNode convertQueryOrInList (Blackboard bb, SqlNode seek, RelDataType targetRowType)
 
RelNode convertRowValues (Blackboard bb, SqlNode rowList, Collection< SqlNode > rows, boolean allowLiteralsOnly, RelDataType targetRowType)
 
RexLiteral convertLiteralInValuesList (SqlNode sqlNode, Blackboard bb, RelDataType rowType, int iField)
 
boolean isRowConstructor (SqlNode node)
 
void findSubQueries (Blackboard bb, SqlNode node, RelOptUtil.Logic logic, boolean registerOnlyScalarSubQueries)
 
RexNode convertOver (Blackboard bb, SqlNode node)
 
void convertUnnest (Blackboard bb, SqlCall call, List< String > fieldNames)
 
void convertIdentifier (Blackboard bb, SqlIdentifier id, SqlNodeList extendedColumns, SqlNodeList tableHints)
 
void convertTemporalTable (Blackboard bb, SqlCall call)
 
Set< RelColumnMapping > getColumnMappings (SqlOperator op)
 
CorrelationUse getCorrelationUse (Blackboard bb, final RelNode r0)
 
boolean isSubQueryNonCorrelated (RelNode subq, Blackboard bb)
 
RexNode convertJoinCondition (Blackboard bb, SqlValidatorNamespace leftNamespace, SqlValidatorNamespace rightNamespace, SqlNode condition, JoinConditionType conditionType, RelNode leftRel, RelNode rightRel)
 
RexNode convertUsing (SqlValidatorNamespace leftNamespace, SqlValidatorNamespace rightNamespace, List< String > nameList)
 
RelNode rewriteAggregateWithGroupId (Blackboard bb, AggregatingSelectScope.Resolved r, AggConverter converter)
 
boolean all (SqlCall call)
 
RelNode createModify (RelOptTable targetTable, RelNode source)
 
RelNode createSource (RelOptTable targetTable, RelNode source, ModifiableView modifiableView, RelDataType delegateRowType)
 
RelOptTable.ToRelContext createToRelContext (List< RelHint > hints)
 
Blackboard createInsertBlackboard (RelOptTable targetTable, RexNode sourceRef, List< String > targetColumnNames)
 
InitializerExpressionFactory getInitializerFactory (SqlValidatorTable validatorTable)
 
RexNode castNullLiteralIfNeeded (RexNode node, RelDataType type)
 
RelNode convertDelete (SqlDelete call)
 
RelNode convertUpdate (SqlUpdate call)
 
RelNode convertMerge (SqlMerge call)
 
RexNode convertIdentifier (Blackboard bb, SqlIdentifier identifier)
 
RelNode convertRowConstructor (Blackboard bb, SqlCall rowConstructor)
 
RelNode convertCursor (Blackboard bb, SubQuery subQuery)
 
RelNode convertMultisets (final List< SqlNode > operands, Blackboard bb)
 
void convertSelectList (Blackboard bb, SqlSelect select, List< SqlNode > orderList)
 
String deriveAlias (final SqlNode node, Collection< String > aliases, final int ordinal)
 
void convertValuesImpl (Blackboard bb, SqlCall values, RelDataType targetRowType)
 
SqlQuantifyOperator negate (SqlQuantifyOperator operator)
 

Static Private Member Functions

static boolean isStream (SqlNode query)
 
static boolean containsInOperator (SqlNode node)
 
static SqlNode pushDownNotForIn (SqlValidatorScope scope, SqlNode sqlNode)
 
static SqlNode reg (SqlValidatorScope scope, SqlNode e)
 
static boolean containsNullLiteral (SqlNodeList valueList)
 
static JoinRelType convertJoinType (JoinType joinType)
 
static boolean desc (RelFieldCollation.Direction direction)
 
static< T > T unwrap (Object o, Class< T > clazz)
 

Private Attributes

SubQueryConverter subQueryConverter
 
final List< SqlDynamicParam > dynamicParamSqlNodes = new ArrayList<>()
 
final SqlOperatorTable opTab
 
final SqlNodeToRexConverter exprConverter
 
final HintStrategyTable hintStrategies
 
int explainParamCount
 
final RelBuilder relBuilder
 
final Map< CorrelationId, DeferredLookupmapCorrelToDeferred = new HashMap<>()
 
final Deque< String > datasetStack = new ArrayDeque<>()
 
final Map< SqlNode, RexNode > mapConvertedNonCorrSubqs = new HashMap<>()
 

Static Private Attributes

static final BigDecimal TWO = BigDecimal.valueOf(2L)
 

Detailed Description

Converts a SQL parse tree (consisting of org.apache.calcite.sql.SqlNode objects) into a relational algebra expression (consisting of org.apache.calcite.rel.RelNode objects).

The public entry points are: convertQuery, convertExpression(SqlNode).

Definition at line 218 of file SqlToRelConverter.java.

Constructor & Destructor Documentation

◆ SqlToRelConverter() [1/3]

org.apache.calcite.sql2rel.SqlToRelConverter.SqlToRelConverter ( RelOptTable.ViewExpander  viewExpander,
SqlValidator  validator,
Prepare.CatalogReader  catalogReader,
RelOptPlanner  planner,
RexBuilder  rexBuilder,
SqlRexConvertletTable  convertletTable 
)
inline

Creates a converter.

Parameters
viewExpanderPreparing statement
validatorValidator
catalogReaderSchema
plannerPlanner
rexBuilderRex builder
convertletTableExpression converter

Definition at line 283 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.catalogReader, org.apache.calcite.sql2rel.SqlToRelConverter.validator, and org.apache.calcite.sql2rel.SqlToRelConverter.viewExpander.

288  {
289  this(viewExpander,
290  validator,
292  RelOptCluster.create(planner, rexBuilder),
293  convertletTable,
294  Config.DEFAULT);
295  }

◆ SqlToRelConverter() [2/3]

org.apache.calcite.sql2rel.SqlToRelConverter.SqlToRelConverter ( RelOptTable.ViewExpander  viewExpander,
SqlValidator  validator,
Prepare.CatalogReader  catalogReader,
RelOptCluster  cluster,
SqlRexConvertletTable  convertletTable 
)
inline

◆ SqlToRelConverter() [3/3]

org.apache.calcite.sql2rel.SqlToRelConverter.SqlToRelConverter ( RelOptTable.ViewExpander  viewExpander,
SqlValidator  validator,
Prepare.CatalogReader  catalogReader,
RelOptCluster  cluster,
SqlRexConvertletTable  convertletTable,
Config  config 
)
inline

Definition at line 312 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.catalogReader, org.apache.calcite.sql2rel.SqlToRelConverter.validator, and org.apache.calcite.sql2rel.SqlToRelConverter.viewExpander.

317  {
318  this.viewExpander = viewExpander;
319  this.opTab = (validator == null) ? SqlStdOperatorTable.instance()
320  : validator.getOperatorTable();
321  this.validator = validator;
323  this.subQueryConverter = new NoOpSubQueryConverter();
324  this.rexBuilder = cluster.getRexBuilder();
325  this.typeFactory = rexBuilder.getTypeFactory();
326  this.exprConverter = new SqlNodeToRexConverterImpl(convertletTable);
327  this.explainParamCount = 0;
328  this.config = new ConfigBuilder().withConfig(config).build();
329  this.relBuilder = config.getRelBuilderFactory().create(cluster, null);
330  this.hintStrategies = config.getHintStrategyTable();
331 
332  cluster.setHintStrategies(this.hintStrategies);
333  this.cluster = Objects.requireNonNull(cluster);
334  }

Member Function Documentation

◆ addConvertedNonCorrSubqs()

void org.apache.calcite.sql2rel.SqlToRelConverter.addConvertedNonCorrSubqs ( Map< SqlNode, RexNode >  alreadyConvertedNonCorrSubqs)
inline

Adds to the current map of non-correlated converted sub-queries the elements from another map that contains non-correlated sub-queries that have been converted by another SqlToRelConverter.

Parameters
alreadyConvertedNonCorrSubqsthe other map

Definition at line 406 of file SqlToRelConverter.java.

407  {
408  mapConvertedNonCorrSubqs.putAll(alreadyConvertedNonCorrSubqs);
409  }
final Map< SqlNode, RexNode > mapConvertedNonCorrSubqs

◆ adjustInputRef()

RexNode org.apache.calcite.sql2rel.SqlToRelConverter.adjustInputRef ( Blackboard  bb,
RexInputRef  inputRef 
)
inlineprotected

Adjusts the type of a reference to an input field to account for nulls introduced by outer joins; and adjusts the offset to match the physical implementation.

Parameters
bbBlackboard
inputRefInput ref
Returns
Adjusted input ref

Definition at line 3819 of file SqlToRelConverter.java.

References field().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertIdentifier().

3819  {
3820  RelDataTypeField field = bb.getRootField(inputRef);
3821  if (field != null) {
3822  return rexBuilder.makeInputRef(field.getType(), inputRef.getIndex());
3823  }
3824  return inputRef;
3825  }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ afterTableFunction()

void org.apache.calcite.sql2rel.SqlToRelConverter.afterTableFunction ( SqlToRelConverter.Blackboard  bb,
SqlCall  call,
LogicalTableFunctionScan  callRel 
)
inlineprotected

Definition at line 2388 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertCollectionTable().

2390  {}
+ Here is the caller graph for this function:

◆ all()

boolean org.apache.calcite.sql2rel.SqlToRelConverter.all ( SqlCall  call)
inlineprivate

Definition at line 3281 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertSetOp().

3281  {
3282  return ((SqlSetOperator) call.getOperator()).isAll();
3283  }
+ Here is the caller graph for this function:

◆ castNullLiteralIfNeeded()

RexNode org.apache.calcite.sql2rel.SqlToRelConverter.castNullLiteralIfNeeded ( RexNode  node,
RelDataType  type 
)
inlineprivate

Definition at line 3550 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertColumnList().

3550  {
3551  if (!RexLiteral.isNullLiteral(node)) {
3552  return node;
3553  }
3554  return rexBuilder.makeCast(type, node);
3555  }
+ Here is the caller graph for this function:

◆ checkConvertedType()

void org.apache.calcite.sql2rel.SqlToRelConverter.checkConvertedType ( SqlNode  query,
RelNode  result 
)
inlineprivate

Definition at line 431 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.catalogReader.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertQuery(), and org.apache.calcite.sql2rel.SqlToRelConverter.decorrelate().

431  {
432  if (query.isA(SqlKind.DML)) {
433  return;
434  }
435  // Verify that conversion from SQL to relational algebra did
436  // not perturb any type information. (We can't do this if the
437  // SQL statement is something like an INSERT which has no
438  // validator type information associated with its result,
439  // hence the namespace check above.)
440  final List<RelDataTypeField> validatedFields =
441  validator.getValidatedNodeType(query).getFieldList();
442  final RelDataType validatedRowType =
443  validator.getTypeFactory().createStructType(Pair.right(validatedFields),
444  SqlValidatorUtil.uniquify(Pair.left(validatedFields),
445  catalogReader.nameMatcher().isCaseSensitive()));
446 
447  final List<RelDataTypeField> convertedFields =
448  result.getRowType().getFieldList().subList(0, validatedFields.size());
449  final RelDataType convertedRowType =
450  validator.getTypeFactory().createStructType(convertedFields);
451 
452  if (!RelOptUtil.equal("validated row type",
453  validatedRowType,
454  "converted row type",
455  convertedRowType,
456  Litmus.IGNORE)) {
457  throw new AssertionError("Conversion to relational algebra failed to "
458  + "preserve datatypes:\n"
459  + "validated type:\n" + validatedRowType.getFullTypeString()
460  + "\nconverted type:\n" + convertedRowType.getFullTypeString() + "\nrel:\n"
461  + RelOptUtil.toString(result));
462  }
463  }
+ Here is the caller graph for this function:

◆ collectInsertTargets()

void org.apache.calcite.sql2rel.SqlToRelConverter.collectInsertTargets ( SqlInsert  call,
final RexNode  sourceRef,
final List< String >  targetColumnNames,
List< RexNode >  columnExprs 
)
inlineprotected

Given an INSERT statement, collects the list of names to be populated and the expressions to put in them.

Parameters
callInsert statement
sourceRefExpression representing a row from the source relational expression
targetColumnNamesList of target column names, to be populated
columnExprsList of expressions, to be populated

Definition at line 3567 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.catalogReader, org.apache.calcite.sql2rel.SqlToRelConverter.createInsertBlackboard(), field(), org.apache.calcite.sql2rel.SqlToRelConverter.getTargetTable(), and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.nameToNodeMap.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertColumnList().

3570  {
3571  final RelOptTable targetTable = getTargetTable(call);
3572  final RelDataType tableRowType = targetTable.getRowType();
3573  SqlNodeList targetColumnList = call.getTargetColumnList();
3574  if (targetColumnList == null) {
3575  if (validator.config().sqlConformance().isInsertSubsetColumnsAllowed()) {
3576  final RelDataType targetRowType =
3577  typeFactory.createStructType(tableRowType.getFieldList().subList(
3578  0, sourceRef.getType().getFieldCount()));
3579  targetColumnNames.addAll(targetRowType.getFieldNames());
3580  } else {
3581  targetColumnNames.addAll(tableRowType.getFieldNames());
3582  }
3583  } else {
3584  for (int i = 0; i < targetColumnList.size(); i++) {
3585  SqlIdentifier id = (SqlIdentifier) targetColumnList.get(i);
3586  RelDataTypeField field = SqlValidatorUtil.getTargetField(
3587  tableRowType, typeFactory, id, catalogReader, targetTable);
3588  assert field != null : "column " + id.toString() + " not found";
3589  targetColumnNames.add(field.getName());
3590  }
3591  }
3592 
3593  final Blackboard bb =
3594  createInsertBlackboard(targetTable, sourceRef, targetColumnNames);
3595 
3596  // Next, assign expressions for generated columns.
3597  final List<ColumnStrategy> strategies = targetTable.getColumnStrategies();
3598  for (String columnName : targetColumnNames) {
3599  final int i = tableRowType.getFieldNames().indexOf(columnName);
3600  final RexNode expr;
3601  switch (strategies.get(i)) {
3602  case STORED:
3603  final InitializerExpressionFactory f =
3604  Util.first(targetTable.unwrap(InitializerExpressionFactory.class),
3605  NullInitializerExpressionFactory.INSTANCE);
3606  expr = f.newColumnDefaultValue(targetTable, i, bb);
3607  break;
3608  case VIRTUAL:
3609  expr = null;
3610  break;
3611  default:
3612  expr = bb.nameToNodeMap.get(columnName);
3613  }
3614  columnExprs.add(expr);
3615  }
3616 
3617  // Remove virtual columns from the list.
3618  for (int i = 0; i < targetColumnNames.size(); i++) {
3619  if (columnExprs.get(i) == null) {
3620  columnExprs.remove(i);
3621  targetColumnNames.remove(i);
3622  --i;
3623  }
3624  }
3625  }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
Blackboard createInsertBlackboard(RelOptTable targetTable, RexNode sourceRef, List< String > targetColumnNames)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ containsInOperator()

static boolean org.apache.calcite.sql2rel.SqlToRelConverter.containsInOperator ( SqlNode  node)
inlinestaticprivate

Returns whether a given node contains a SqlInOperator.

Parameters
nodea RexNode tree

Definition at line 843 of file SqlToRelConverter.java.

References Void.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.pushDownNotForIn().

843  {
844  try {
845  SqlVisitor<Void> visitor = new SqlBasicVisitor<Void>() {
846  public Void visit(SqlCall call) {
847  if (call.getOperator() instanceof SqlInOperator) {
848  throw new Util.FoundOne(call);
849  }
850  return super.visit(call);
851  }
852  };
853  node.accept(visitor);
854  return false;
855  } catch (Util.FoundOne e) {
856  Util.swallow(e, null);
857  return true;
858  }
859  }
+ Here is the caller graph for this function:

◆ containsNullLiteral()

static boolean org.apache.calcite.sql2rel.SqlToRelConverter.containsNullLiteral ( SqlNodeList  valueList)
inlinestaticprivate

Definition at line 1328 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.substituteSubQuery().

1328  {
1329  for (SqlNode node : valueList.getList()) {
1330  if (node instanceof SqlLiteral) {
1331  SqlLiteral lit = (SqlLiteral) node;
1332  if (lit.getValue() == null) {
1333  return true;
1334  }
1335  }
1336  }
1337  return false;
1338  }
+ Here is the caller graph for this function:

◆ convertAgg()

void org.apache.calcite.sql2rel.SqlToRelConverter.convertAgg ( Blackboard  bb,
SqlSelect  select,
List< SqlNode >  orderExprList 
)
inlineprotected

Converts the SELECT, GROUP BY and HAVING clauses of an aggregate query.

This method extracts SELECT, GROUP BY and HAVING clauses, and creates an AggConverter, then delegates to createAggImpl. Derived class may override this method to change any of those clauses or specify a different AggConverter.

Parameters
bbScope within which to resolve identifiers
selectQuery
orderExprListAdditional expressions needed to implement ORDER BY

Definition at line 2759 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.createAggImpl(), and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertSelectImpl().

2760  {
2761  assert bb.root != null : "precondition: child != null";
2762  SqlNodeList groupList = select.getGroup();
2763  SqlNodeList selectList = select.getSelectList();
2764  SqlNode having = select.getHaving();
2765 
2766  final AggConverter aggConverter = new AggConverter(bb, select);
2767  createAggImpl(bb, aggConverter, selectList, groupList, having, orderExprList);
2768  }
final void createAggImpl(Blackboard bb, final AggConverter aggConverter, SqlNodeList selectList, SqlNodeList groupList, SqlNode having, List< SqlNode > orderExprList)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertCollectionTable()

void org.apache.calcite.sql2rel.SqlToRelConverter.convertCollectionTable ( Blackboard  bb,
SqlCall  call 
)
inlineprotected

Definition at line 2337 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.afterTableFunction(), org.apache.calcite.sql2rel.SqlToRelConverter.convertQuery(), org.apache.calcite.sql2rel.SqlToRelConverter.getColumnMappings(), org.apache.calcite.sql2rel.SqlToRelConverter.replaceSubQueries(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.scope, org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setRoot(), and org.apache.calcite.sql2rel.SqlToRelConverter.toRel().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom().

2337  {
2338  final SqlOperator operator = call.getOperator();
2339  if (operator == SqlStdOperatorTable.TABLESAMPLE) {
2340  final String sampleName =
2341  SqlLiteral.unchain(call.operand(0)).getValueAs(String.class);
2342  datasetStack.push(sampleName);
2343  SqlCall cursorCall = call.operand(1);
2344  SqlNode query = cursorCall.operand(0);
2345  RelNode converted = convertQuery(query, false, false).rel;
2346  bb.setRoot(converted, false);
2347  datasetStack.pop();
2348  return;
2349  }
2350  replaceSubQueries(bb, call, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
2351 
2352  // Expand table macro if possible. It's more efficient than
2353  // LogicalTableFunctionScan.
2354  final SqlCallBinding callBinding =
2355  new SqlCallBinding(bb.scope.getValidator(), bb.scope, call);
2356  if (operator instanceof SqlUserDefinedTableMacro) {
2357  final SqlUserDefinedTableMacro udf = (SqlUserDefinedTableMacro) operator;
2358  final TranslatableTable table = udf.getTable(typeFactory, callBinding.operands());
2359  final RelDataType rowType = table.getRowType(typeFactory);
2360  RelOptTable relOptTable =
2361  RelOptTableImpl.create(null, rowType, table, udf.getNameAsId().names);
2362  RelNode converted = toRel(relOptTable, ImmutableList.of());
2363  bb.setRoot(converted, true);
2364  return;
2365  }
2366 
2367  Type elementType;
2368  if (operator instanceof SqlUserDefinedTableFunction) {
2369  SqlUserDefinedTableFunction udtf = (SqlUserDefinedTableFunction) operator;
2370  elementType = udtf.getElementType(typeFactory, callBinding.operands());
2371  } else {
2372  elementType = null;
2373  }
2374 
2375  RexNode rexCall = bb.convertExpression(call);
2376  final List<RelNode> inputs = bb.retrieveCursors();
2377  Set<RelColumnMapping> columnMappings = getColumnMappings(operator);
2378  LogicalTableFunctionScan callRel = LogicalTableFunctionScan.create(cluster,
2379  inputs,
2380  rexCall,
2381  elementType,
2382  validator.getValidatedNodeType(call),
2383  columnMappings);
2384  bb.setRoot(callRel, true);
2385  afterTableFunction(bb, call, callRel);
2386  }
void afterTableFunction(SqlToRelConverter.Blackboard bb, SqlCall call, LogicalTableFunctionScan callRel)
RelNode toRel(final RelOptTable table, final List< RelHint > hints)
void replaceSubQueries(final Blackboard bb, final SqlNode expr, RelOptUtil.Logic logic)
Set< RelColumnMapping > getColumnMappings(SqlOperator op)
RelRoot convertQuery(SqlNode query, final boolean needsValidation, final boolean top)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertColumnList()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.convertColumnList ( final SqlInsert  call,
RelNode  source 
)
inlineprotected

Creates a source for an INSERT statement.

If the column list is not specified, source expressions match target columns in order.

If the column list is specified, Source expressions are mapped to target columns by name via targetColumnList, and may not cover the entire target table. So, we'll make up a full row, using a combination of default values and the source expressions provided.

Parameters
callInsert expression
sourceSource relational expression
Returns
Converted INSERT statement

Definition at line 3454 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.castNullLiteralIfNeeded(), org.apache.calcite.sql2rel.SqlToRelConverter.catalogReader, org.apache.calcite.sql2rel.SqlToRelConverter.collectInsertTargets(), org.apache.calcite.sql2rel.SqlToRelConverter.createInsertBlackboard(), field(), org.apache.calcite.sql2rel.SqlToRelConverter.getInitializerFactory(), and org.apache.calcite.sql2rel.SqlToRelConverter.getTargetTable().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertInsert().

3454  {
3455  RelDataType sourceRowType = source.getRowType();
3456  final RexNode sourceRef = rexBuilder.makeRangeReference(sourceRowType, 0, false);
3457  final List<String> targetColumnNames = new ArrayList<>();
3458  final List<RexNode> columnExprs = new ArrayList<>();
3459  collectInsertTargets(call, sourceRef, targetColumnNames, columnExprs);
3460 
3461  final RelOptTable targetTable = getTargetTable(call);
3462  final RelDataType targetRowType = RelOptTableImpl.realRowType(targetTable);
3463  final List<RelDataTypeField> targetFields = targetRowType.getFieldList();
3464  final List<RexNode> sourceExps =
3465  new ArrayList<>(Collections.nCopies(targetFields.size(), null));
3466  final List<String> fieldNames =
3467  new ArrayList<>(Collections.nCopies(targetFields.size(), null));
3468 
3469  final InitializerExpressionFactory initializerFactory =
3470  getInitializerFactory(validator.getNamespace(call).getTable());
3471 
3472  // Walk the name list and place the associated value in the
3473  // expression list according to the ordinal value returned from
3474  // the table construct, leaving nulls in the list for columns
3475  // that are not referenced.
3476  final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
3477  for (Pair<String, RexNode> p : Pair.zip(targetColumnNames, columnExprs)) {
3478  RelDataTypeField field = nameMatcher.field(targetRowType, p.left);
3479  assert field != null : "column " + p.left + " not found";
3480  sourceExps.set(field.getIndex(), p.right);
3481  }
3482 
3483  // Lazily create a blackboard that contains all non-generated columns.
3484  final Supplier<Blackboard> bb =
3485  () -> createInsertBlackboard(targetTable, sourceRef, targetColumnNames);
3486 
3487  // Walk the expression list and get default values for any columns
3488  // that were not supplied in the statement. Get field names too.
3489  for (int i = 0; i < targetFields.size(); ++i) {
3490  final RelDataTypeField field = targetFields.get(i);
3491  final String fieldName = field.getName();
3492  fieldNames.set(i, fieldName);
3493  if (sourceExps.get(i) == null || sourceExps.get(i).getKind() == SqlKind.DEFAULT) {
3494  sourceExps.set(
3495  i, initializerFactory.newColumnDefaultValue(targetTable, i, bb.get()));
3496 
3497  // bare nulls are dangerous in the wrong hands
3498  sourceExps.set(i, castNullLiteralIfNeeded(sourceExps.get(i), field.getType()));
3499  }
3500  }
3501 
3502  return relBuilder.push(source).projectNamed(sourceExps, fieldNames, false).build();
3503  }
RexNode castNullLiteralIfNeeded(RexNode node, RelDataType type)
InitializerExpressionFactory getInitializerFactory(SqlValidatorTable validatorTable)
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
void collectInsertTargets(SqlInsert call, final RexNode sourceRef, final List< String > targetColumnNames, List< RexNode > columnExprs)
Blackboard createInsertBlackboard(RelOptTable targetTable, RexNode sourceRef, List< String > targetColumnNames)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertCursor()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.convertCursor ( Blackboard  bb,
SubQuery  subQuery 
)
inlineprivate

Definition at line 3840 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.convertQuery(), and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.cursors.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.substituteSubQuery().

3840  {
3841  final SqlCall cursorCall = (SqlCall) subQuery.node;
3842  assert cursorCall.operandCount() == 1;
3843  SqlNode query = cursorCall.operand(0);
3844  RelNode converted = convertQuery(query, false, false).rel;
3845  int iCursor = bb.cursors.size();
3846  bb.cursors.add(converted);
3847  subQuery.expr = new RexInputRef(iCursor, converted.getRowType());
3848  return converted;
3849  }
RelRoot convertQuery(SqlNode query, final boolean needsValidation, final boolean top)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertDelete()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.convertDelete ( SqlDelete  call)
inlineprivate

Definition at line 3627 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.catalogReader, org.apache.calcite.sql2rel.SqlToRelConverter.convertSelect(), and org.apache.calcite.sql2rel.SqlToRelConverter.getTargetTable().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryRecursive().

3627  {
3628  RelOptTable targetTable = getTargetTable(call);
3629  RelNode sourceRel = convertSelect(call.getSourceSelect(), false);
3630  return LogicalTableModify.create(targetTable,
3631  catalogReader,
3632  sourceRel,
3633  LogicalTableModify.Operation.DELETE,
3634  null,
3635  null,
3636  false);
3637  }
RelNode convertSelect(SqlSelect select, boolean top)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertDynamicParam()

RexDynamicParam org.apache.calcite.sql2rel.SqlToRelConverter.convertDynamicParam ( final SqlDynamicParam  dynamicParam)
inline

Definition at line 3067 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.getDynamicParamType().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.lookupExp().

3067  {
3068  // REVIEW jvs 8-Jan-2005: dynamic params may be encountered out of
3069  // order. Should probably cross-check with the count from the parser
3070  // at the end and make sure they all got filled in. Why doesn't List
3071  // have a resize() method?!? Make this a utility.
3072  while (dynamicParam.getIndex() >= dynamicParamSqlNodes.size()) {
3073  dynamicParamSqlNodes.add(null);
3074  }
3075 
3076  dynamicParamSqlNodes.set(dynamicParam.getIndex(), dynamicParam);
3077  return rexBuilder.makeDynamicParam(
3078  getDynamicParamType(dynamicParam.getIndex()), dynamicParam.getIndex());
3079  }
final List< SqlDynamicParam > dynamicParamSqlNodes
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertExists()

RelOptUtil.Exists org.apache.calcite.sql2rel.SqlToRelConverter.convertExists ( SqlNode  seek,
RelOptUtil.SubQueryType  subQueryType,
RelOptUtil.Logic  logic,
boolean  notIn,
RelDataType  targetDataType 
)
inlineprivate

Converts an EXISTS or IN predicate into a join. For EXISTS, the sub-query produces an indicator variable, and the result is a relational expression which outer joins that indicator to the original query. After performing the outer join, the condition will be TRUE if the EXISTS condition holds, NULL otherwise.

Parameters
seekA query, for example 'select * from emp' or 'values (1,2,3)' or '('Foo', 34)'.
subQueryTypeWhether sub-query is IN, EXISTS or scalar
logicWhether the answer needs to be in full 3-valued logic (TRUE, FALSE, UNKNOWN) will be required, or whether we can accept an approximation (say representing UNKNOWN as FALSE)
notInWhether the operation is NOT IN
Returns
join expression

Definition at line 1522 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryOrInList(), and org.apache.calcite.sql2rel.SqlToRelConverter.createBlackboard().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.substituteSubQuery().

1526  {
1527  final SqlValidatorScope seekScope = (seek instanceof SqlSelect)
1528  ? validator.getSelectScope((SqlSelect) seek)
1529  : null;
1530  final Blackboard seekBb = createBlackboard(seekScope, null, false);
1531  RelNode seekRel = convertQueryOrInList(seekBb, seek, targetDataType);
1532 
1533  return RelOptUtil.createExistsPlan(seekRel, subQueryType, logic, notIn, relBuilder);
1534  }
RelNode convertQueryOrInList(Blackboard bb, SqlNode seek, RelDataType targetRowType)
Blackboard createBlackboard(SqlValidatorScope scope, Map< String, RexNode > nameToNodeMap, boolean top)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertExpression() [1/2]

RexNode org.apache.calcite.sql2rel.SqlToRelConverter.convertExpression ( SqlNode  node)
inline

Converts an expression from SqlNode to RexNode format.

Parameters
nodeExpression to translate
Returns
Converted expression

Definition at line 1789 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.createBlackboard().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertOrder(), and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.lookupExp().

1789  {
1790  Map<String, RelDataType> nameToTypeMap = Collections.emptyMap();
1791  final ParameterScope scope =
1792  new ParameterScope((SqlValidatorImpl) validator, nameToTypeMap);
1793  final Blackboard bb = createBlackboard(scope, null, false);
1794  return bb.convertExpression(node);
1795  }
Blackboard createBlackboard(SqlValidatorScope scope, Map< String, RexNode > nameToNodeMap, boolean top)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertExpression() [2/2]

RexNode org.apache.calcite.sql2rel.SqlToRelConverter.convertExpression ( SqlNode  node,
Map< String, RexNode >  nameToNodeMap 
)
inline

Converts an expression from SqlNode to RexNode format, mapping identifier references to predefined expressions.

Parameters
nodeExpression to translate
nameToNodeMapmap from String to RexNode; when an SqlIdentifier is encountered, it is used as a key and translated to the corresponding value from this map
Returns
Converted expression

Definition at line 1808 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.createBlackboard().

1808  {
1809  final Map<String, RelDataType> nameToTypeMap = new HashMap<>();
1810  for (Map.Entry<String, RexNode> entry : nameToNodeMap.entrySet()) {
1811  nameToTypeMap.put(entry.getKey(), entry.getValue().getType());
1812  }
1813  final ParameterScope scope =
1814  new ParameterScope((SqlValidatorImpl) validator, nameToTypeMap);
1815  final Blackboard bb = createBlackboard(scope, nameToNodeMap, false);
1816  return bb.convertExpression(node);
1817  }
Blackboard createBlackboard(SqlValidatorScope scope, Map< String, RexNode > nameToNodeMap, boolean top)
+ Here is the call graph for this function:

◆ convertExtendedExpression()

RexNode org.apache.calcite.sql2rel.SqlToRelConverter.convertExtendedExpression ( SqlNode  node,
Blackboard  bb 
)
inlineprotected

Converts a non-standard expression.

This method is an extension-point that derived classes can override. If this method returns a null result, the normal expression translation process will proceed. The default implementation always returns null.

Parameters
nodeExpression
bbBlackboard
Returns
null to proceed with the usual expression translation process

Definition at line 1831 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.lookupExp().

1831  {
1832  return null;
1833  }
+ Here is the caller graph for this function:

◆ convertFrom() [1/2]

void org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom ( Blackboard  bb,
SqlNode  from 
)
inlineprotected

Definition at line 1927 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom(), org.apache.calcite.sql2rel.SqlToRelConverter.convertIdentifier(), org.apache.calcite.sql2rel.SqlToRelConverter.convertMatchRecognize(), org.apache.calcite.sql2rel.SqlToRelConverter.convertSelectImpl(), and org.apache.calcite.sql2rel.SqlToRelConverter.convertTemporalTable().

1927  {
1928  convertFrom(bb, from, Collections.emptyList());
1929  }
void convertFrom(Blackboard bb, SqlNode from)
+ Here is the caller graph for this function:

◆ convertFrom() [2/2]

void org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom ( Blackboard  bb,
SqlNode  from,
List< String >  fieldNames 
)
inlineprotected

Converts a FROM clause into a relational expression.

Parameters
bbScope within which to resolve identifiers
fromFROM clause of a query. Examples include:
              <ul>
              <li>a single table ("SALES.EMP"),
              <li>an aliased table ("EMP AS E"),
              <li>a list of tables ("EMP, DEPT"),
              <li>an ANSI Join expression ("EMP JOIN DEPT ON EMP.DEPTNO =
              DEPT.DEPTNO"),
              <li>a VALUES clause ("VALUES ('Fred', 20)"),
              <li>a query ("(SELECT * FROM EMP WHERE GENDER = 'F')"),
              <li>or any combination of the above.
              </ul>
fieldNamesField aliases, usually come from AS clause

Definition at line 1949 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.catalogReader, org.apache.calcite.sql2rel.SqlToRelConverter.convertCollectionTable(), org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom(), org.apache.calcite.sql2rel.SqlToRelConverter.convertIdentifier(), org.apache.calcite.sql2rel.SqlToRelConverter.convertJoinCondition(), org.apache.calcite.sql2rel.SqlToRelConverter.convertJoinType(), org.apache.calcite.sql2rel.SqlToRelConverter.convertMatchRecognize(), org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryRecursive(), org.apache.calcite.sql2rel.SqlToRelConverter.convertTemporalTable(), org.apache.calcite.sql2rel.SqlToRelConverter.convertUnnest(), org.apache.calcite.sql2rel.SqlToRelConverter.convertUsing(), org.apache.calcite.sql2rel.SqlToRelConverter.convertValuesImpl(), org.apache.calcite.sql2rel.SqlToRelConverter.createBlackboard(), org.apache.calcite.sql2rel.SqlToRelConverter.createJoin(), join(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root, org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.scope, and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setRoot().

1949  {
1950  if (from == null) {
1951  bb.setRoot(LogicalValues.createOneRow(cluster), false);
1952  return;
1953  }
1954 
1955  final SqlCall call;
1956  final SqlNode[] operands;
1957  switch (from.getKind()) {
1958  case MATCH_RECOGNIZE:
1959  convertMatchRecognize(bb, (SqlCall) from);
1960  return;
1961 
1962  case AS:
1963  call = (SqlCall) from;
1964  SqlNode firstOperand = call.operand(0);
1965  final List<String> fieldNameList = new ArrayList<>();
1966  if (call.operandCount() > 2) {
1967  for (SqlNode node : Util.skip(call.getOperandList(), 2)) {
1968  fieldNameList.add(((SqlIdentifier) node).getSimple());
1969  }
1970  }
1971  convertFrom(bb, firstOperand, fieldNameList);
1972  return;
1973 
1974  case WITH_ITEM:
1975  convertFrom(bb, ((SqlWithItem) from).query);
1976  return;
1977 
1978  case WITH:
1979  convertFrom(bb, ((SqlWith) from).body);
1980  return;
1981 
1982  case TABLESAMPLE:
1983  operands = ((SqlBasicCall) from).getOperands();
1984  SqlSampleSpec sampleSpec = SqlLiteral.sampleValue(operands[1]);
1985  if (sampleSpec instanceof SqlSampleSpec.SqlSubstitutionSampleSpec) {
1986  String sampleName =
1987  ((SqlSampleSpec.SqlSubstitutionSampleSpec) sampleSpec).getName();
1988  datasetStack.push(sampleName);
1989  convertFrom(bb, operands[0]);
1990  datasetStack.pop();
1991  } else if (sampleSpec instanceof SqlSampleSpec.SqlTableSampleSpec) {
1992  SqlSampleSpec.SqlTableSampleSpec tableSampleSpec =
1993  (SqlSampleSpec.SqlTableSampleSpec) sampleSpec;
1994  convertFrom(bb, operands[0]);
1995  RelOptSamplingParameters params =
1996  new RelOptSamplingParameters(tableSampleSpec.isBernoulli(),
1997  tableSampleSpec.getSamplePercentage(),
1998  tableSampleSpec.isRepeatable(),
1999  tableSampleSpec.getRepeatableSeed());
2000  bb.setRoot(new Sample(cluster, bb.root, params), false);
2001  } else {
2002  throw new AssertionError("unknown TABLESAMPLE type: " + sampleSpec);
2003  }
2004  return;
2005 
2006  case TABLE_REF:
2007  call = (SqlCall) from;
2008  convertIdentifier(bb, call.operand(0), null, call.operand(1));
2009  return;
2010 
2011  case IDENTIFIER:
2012  convertIdentifier(bb, (SqlIdentifier) from, null, null);
2013  return;
2014 
2015  case EXTEND:
2016  call = (SqlCall) from;
2017  final SqlNode operand0 = call.getOperandList().get(0);
2018  final SqlIdentifier id = operand0.getKind() == SqlKind.TABLE_REF
2019  ? ((SqlCall) operand0).operand(0)
2020  : (SqlIdentifier) operand0;
2021  SqlNodeList extendedColumns = (SqlNodeList) call.getOperandList().get(1);
2022  convertIdentifier(bb, id, extendedColumns, null);
2023  return;
2024 
2025  case SNAPSHOT:
2026  convertTemporalTable(bb, (SqlCall) from);
2027  return;
2028 
2029  case JOIN:
2030  final SqlJoin join = (SqlJoin) from;
2031  final SqlValidatorScope scope = validator.getJoinScope(from);
2032  final Blackboard fromBlackboard = createBlackboard(scope, null, false);
2033  SqlNode left = join.getLeft();
2034  SqlNode right = join.getRight();
2035  final boolean isNatural = join.isNatural();
2036  final JoinType joinType = join.getJoinType();
2037  final SqlValidatorScope leftScope = Util.first(
2038  validator.getJoinScope(left), ((DelegatingScope) bb.scope).getParent());
2039  final Blackboard leftBlackboard = createBlackboard(leftScope, null, false);
2040  final SqlValidatorScope rightScope = Util.first(
2041  validator.getJoinScope(right), ((DelegatingScope) bb.scope).getParent());
2042  final Blackboard rightBlackboard = createBlackboard(rightScope, null, false);
2043  convertFrom(leftBlackboard, left);
2044  RelNode leftRel = leftBlackboard.root;
2045  convertFrom(rightBlackboard, right);
2046  RelNode rightRel = rightBlackboard.root;
2047  JoinRelType convertedJoinType = convertJoinType(joinType);
2048  RexNode conditionExp;
2049  final SqlValidatorNamespace leftNamespace = validator.getNamespace(left);
2050  final SqlValidatorNamespace rightNamespace = validator.getNamespace(right);
2051  if (isNatural) {
2052  final RelDataType leftRowType = leftNamespace.getRowType();
2053  final RelDataType rightRowType = rightNamespace.getRowType();
2054  final List<String> columnList = SqlValidatorUtil.deriveNaturalJoinColumnList(
2055  catalogReader.nameMatcher(), leftRowType, rightRowType);
2056  conditionExp = convertUsing(leftNamespace, rightNamespace, columnList);
2057  } else {
2058  conditionExp = convertJoinCondition(fromBlackboard,
2059  leftNamespace,
2060  rightNamespace,
2061  join.getCondition(),
2062  join.getConditionType(),
2063  leftRel,
2064  rightRel);
2065  }
2066 
2067  final RelNode joinRel = createJoin(
2068  fromBlackboard, leftRel, rightRel, conditionExp, convertedJoinType);
2069  bb.setRoot(joinRel, false);
2070  return;
2071 
2072  case SELECT:
2073  case INTERSECT:
2074  case EXCEPT:
2075  case UNION:
2076  final RelNode rel = convertQueryRecursive(from, false, null).project();
2077  bb.setRoot(rel, true);
2078  return;
2079 
2080  case VALUES:
2081  convertValuesImpl(bb, (SqlCall) from, null);
2082  if (fieldNames.size() > 0) {
2083  bb.setRoot(relBuilder.push(bb.root).rename(fieldNames).build(), true);
2084  }
2085  return;
2086 
2087  case UNNEST:
2088  convertUnnest(bb, (SqlCall) from, fieldNames);
2089  return;
2090 
2091  case COLLECTION_TABLE:
2092  call = (SqlCall) from;
2093 
2094  // Dig out real call; TABLE() wrapper is just syntactic.
2095  assert call.getOperandList().size() == 1;
2096  final SqlCall call2 = call.operand(0);
2097  convertCollectionTable(bb, call2);
2098  return;
2099 
2100  default:
2101  throw new AssertionError("not a join operator " + from);
2102  }
2103  }
JoinType
Definition: sqldefs.h:107
void convertCollectionTable(Blackboard bb, SqlCall call)
std::string join(T const &container, std::string const &delim)
void convertValuesImpl(Blackboard bb, SqlCall values, RelDataType targetRowType)
void convertFrom(Blackboard bb, SqlNode from)
RelRoot convertQueryRecursive(SqlNode query, boolean top, RelDataType targetRowType)
void convertUnnest(Blackboard bb, SqlCall call, List< String > fieldNames)
RexNode convertUsing(SqlValidatorNamespace leftNamespace, SqlValidatorNamespace rightNamespace, List< String > nameList)
RexNode convertJoinCondition(Blackboard bb, SqlValidatorNamespace leftNamespace, SqlValidatorNamespace rightNamespace, SqlNode condition, JoinConditionType conditionType, RelNode leftRel, RelNode rightRel)
void convertIdentifier(Blackboard bb, SqlIdentifier id, SqlNodeList extendedColumns, SqlNodeList tableHints)
void convertMatchRecognize(Blackboard bb, SqlCall call)
RelNode createJoin(Blackboard bb, RelNode leftRel, RelNode rightRel, RexNode joinCond, JoinRelType joinType)
void convertTemporalTable(Blackboard bb, SqlCall call)
Blackboard createBlackboard(SqlValidatorScope scope, Map< String, RexNode > nameToNodeMap, boolean top)
static JoinRelType convertJoinType(JoinType joinType)
+ Here is the call graph for this function:

◆ convertIdentifier() [1/2]

void org.apache.calcite.sql2rel.SqlToRelConverter.convertIdentifier ( Blackboard  bb,
SqlIdentifier  id,
SqlNodeList  extendedColumns,
SqlNodeList  tableHints 
)
inlineprivate

Definition at line 2304 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.catalogReader, org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setDataset(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setRoot(), and org.apache.calcite.sql2rel.SqlToRelConverter.toRel().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom(), and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.lookupExp().

2307  {
2308  final SqlValidatorNamespace fromNamespace = validator.getNamespace(id).resolve();
2309  if (fromNamespace.getNode() != null) {
2310  convertFrom(bb, fromNamespace.getNode());
2311  return;
2312  }
2313  final String datasetName = datasetStack.isEmpty() ? null : datasetStack.peek();
2314  final boolean[] usedDataset = {false};
2315  RelOptTable table = SqlValidatorUtil.getRelOptTable(
2316  fromNamespace, catalogReader, datasetName, usedDataset);
2317  if (extendedColumns != null && extendedColumns.size() > 0) {
2318  assert table != null;
2319  final SqlValidatorTable validatorTable = table.unwrap(SqlValidatorTable.class);
2320  final List<RelDataTypeField> extendedFields = SqlValidatorUtil.getExtendedColumns(
2321  validator, validatorTable, extendedColumns);
2322  table = table.extend(extendedFields);
2323  }
2324  final RelNode tableRel;
2325  // Review Danny 2020-01-13: hacky to construct a new table scan
2326  // in order to apply the hint strategies.
2327  final List<RelHint> hints =
2328  hintStrategies.apply(SqlUtil.getRelHint(hintStrategies, tableHints),
2329  LogicalTableScan.create(cluster, table, ImmutableList.of()));
2330  tableRel = toRel(table, hints);
2331  bb.setRoot(tableRel, true);
2332  if (usedDataset[0]) {
2333  bb.setDataset(datasetName);
2334  }
2335  }
RelNode toRel(final RelOptTable table, final List< RelHint > hints)
void convertFrom(Blackboard bb, SqlNode from)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertIdentifier() [2/2]

RexNode org.apache.calcite.sql2rel.SqlToRelConverter.convertIdentifier ( Blackboard  bb,
SqlIdentifier  identifier 
)
inlineprivate

Converts an identifier into an expression in a given scope. For example, the "empno" in "select empno from emp join dept" becomes "emp.empno".

Definition at line 3760 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.adjustInputRef(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.isPatternVarRef, org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.lookupExp(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.mapCorrelateToRex, and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.scope.

3760  {
3761  // first check for reserved identifiers like CURRENT_USER
3762  final SqlCall call = bb.getValidator().makeNullaryCall(identifier);
3763  if (call != null) {
3764  return bb.convertExpression(call);
3765  }
3766 
3767  String pv = null;
3768  if (bb.isPatternVarRef && identifier.names.size() > 1) {
3769  pv = identifier.names.get(0);
3770  }
3771 
3772  final SqlQualified qualified;
3773  if (bb.scope != null) {
3774  qualified = bb.scope.fullyQualify(identifier);
3775  } else {
3776  qualified = SqlQualified.create(null, 1, null, identifier);
3777  }
3778  final Pair<RexNode, Map<String, Integer>> e0 = bb.lookupExp(qualified);
3779  RexNode e = e0.left;
3780  for (String name : qualified.suffix()) {
3781  if (e == e0.left && e0.right != null) {
3782  int i = e0.right.get(name);
3783  e = rexBuilder.makeFieldAccess(e, i);
3784  } else {
3785  final boolean caseSensitive = true; // name already fully-qualified
3786  if (identifier.isStar() && bb.scope instanceof MatchRecognizeScope) {
3787  e = rexBuilder.makeFieldAccess(e, 0);
3788  } else {
3789  e = rexBuilder.makeFieldAccess(e, name, caseSensitive);
3790  }
3791  }
3792  }
3793  if (e instanceof RexInputRef) {
3794  // adjust the type to account for nulls introduced by outer joins
3795  e = adjustInputRef(bb, (RexInputRef) e);
3796  if (pv != null) {
3797  e = RexPatternFieldRef.of(pv, (RexInputRef) e);
3798  }
3799  }
3800 
3801  if (e0.left instanceof RexCorrelVariable) {
3802  assert e instanceof RexFieldAccess;
3803  final RexNode prev = bb.mapCorrelateToRex.put(
3804  ((RexCorrelVariable) e0.left).id, (RexFieldAccess) e);
3805  assert prev == null;
3806  }
3807  return e;
3808  }
RexNode adjustInputRef(Blackboard bb, RexInputRef inputRef)
+ Here is the call graph for this function:

◆ convertInsert()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.convertInsert ( SqlInsert  call)
inlineprotected

Definition at line 3285 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.convertColumnList(), org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryRecursive(), org.apache.calcite.sql2rel.SqlToRelConverter.createModify(), and org.apache.calcite.sql2rel.SqlToRelConverter.getTargetTable().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertMerge(), and org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryRecursive().

3285  {
3286  RelOptTable targetTable = getTargetTable(call);
3287 
3288  final RelDataType targetRowType = validator.getValidatedNodeType(call);
3289  assert targetRowType != null;
3290  RelNode sourceRel =
3291  convertQueryRecursive(call.getSource(), true, targetRowType).project();
3292  RelNode massagedRel = convertColumnList(call, sourceRel);
3293 
3294  return createModify(targetTable, massagedRel);
3295  }
RelRoot convertQueryRecursive(SqlNode query, boolean top, RelDataType targetRowType)
RelNode createModify(RelOptTable targetTable, RelNode source)
RelNode convertColumnList(final SqlInsert call, RelNode source)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertInToOr()

RexNode org.apache.calcite.sql2rel.SqlToRelConverter.convertInToOr ( final Blackboard  bb,
final List< RexNode >  leftKeys,
SqlNodeList  valuesList,
SqlInOperator  op 
)
inlineprivate

Converts "x IN (1, 2, ...)" to "x=1 OR x=2 OR ...".

Parameters
leftKeysLHS
valuesListRHS
opThe operator (IN, NOT IN, > SOME, ...)
Returns
converted expression

Definition at line 1428 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.ensureSqlType().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.substituteSubQuery().

1431  {
1432  final List<RexNode> comparisons = new ArrayList<>();
1433  for (SqlNode rightVals : valuesList) {
1434  RexNode rexComparison;
1435  final SqlOperator comparisonOp;
1436  if (op instanceof SqlQuantifyOperator) {
1437  comparisonOp = RelOptUtil.op(
1438  ((SqlQuantifyOperator) op).comparisonKind, SqlStdOperatorTable.EQUALS);
1439  } else {
1440  comparisonOp = SqlStdOperatorTable.EQUALS;
1441  }
1442  if (leftKeys.size() == 1) {
1443  rexComparison = rexBuilder.makeCall(comparisonOp,
1444  leftKeys.get(0),
1445  ensureSqlType(
1446  leftKeys.get(0).getType(), bb.convertExpression(rightVals)));
1447  } else {
1448  assert rightVals instanceof SqlCall;
1449  final SqlBasicCall call = (SqlBasicCall) rightVals;
1450  assert (call.getOperator() instanceof SqlRowOperator)
1451  && call.operandCount() == leftKeys.size();
1452  rexComparison = RexUtil.composeConjunction(rexBuilder,
1453  Iterables.transform(Pair.zip(leftKeys, call.getOperandList()),
1454  pair
1455  -> rexBuilder.makeCall(comparisonOp,
1456  pair.left,
1457  ensureSqlType(pair.left.getType(),
1458  bb.convertExpression(pair.right)))));
1459  }
1460  comparisons.add(rexComparison);
1461  }
1462 
1463  switch (op.kind) {
1464  case ALL:
1465  return RexUtil.composeConjunction(rexBuilder, comparisons, true);
1466  case NOT_IN:
1467  return rexBuilder.makeCall(SqlStdOperatorTable.NOT,
1468  RexUtil.composeDisjunction(rexBuilder, comparisons, true));
1469  case IN:
1470  case SOME:
1471  return RexUtil.composeDisjunction(rexBuilder, comparisons, true);
1472  default:
1473  throw new AssertionError();
1474  }
1475  }
RexNode ensureSqlType(RelDataType type, RexNode node)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertJoinCondition()

RexNode org.apache.calcite.sql2rel.SqlToRelConverter.convertJoinCondition ( Blackboard  bb,
SqlValidatorNamespace  leftNamespace,
SqlValidatorNamespace  rightNamespace,
SqlNode  condition,
JoinConditionType  conditionType,
RelNode  leftRel,
RelNode  rightRel 
)
inlineprivate

Definition at line 2669 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.convertUsing(), org.apache.calcite.sql2rel.SqlToRelConverter.replaceSubQueries(), and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setRoot().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom().

2675  {
2676  if (condition == null) {
2677  return rexBuilder.makeLiteral(true);
2678  }
2679  bb.setRoot(ImmutableList.of(leftRel, rightRel));
2680  replaceSubQueries(bb, condition, RelOptUtil.Logic.UNKNOWN_AS_FALSE);
2681  switch (conditionType) {
2682  case ON:
2683  bb.setRoot(ImmutableList.of(leftRel, rightRel));
2684  return bb.convertExpression(condition);
2685  case USING:
2686  final SqlNodeList list = (SqlNodeList) condition;
2687  final List<String> nameList = new ArrayList<>();
2688  for (SqlNode columnName : list) {
2689  final SqlIdentifier id = (SqlIdentifier) columnName;
2690  String name = id.getSimple();
2691  nameList.add(name);
2692  }
2693  return convertUsing(leftNamespace, rightNamespace, nameList);
2694  default:
2695  throw Util.unexpected(conditionType);
2696  }
2697  }
RexNode convertUsing(SqlValidatorNamespace leftNamespace, SqlValidatorNamespace rightNamespace, List< String > nameList)
void replaceSubQueries(final Blackboard bb, final SqlNode expr, RelOptUtil.Logic logic)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertJoinType()

static JoinRelType org.apache.calcite.sql2rel.SqlToRelConverter.convertJoinType ( JoinType  joinType)
inlinestaticprivate

Definition at line 2729 of file SqlToRelConverter.java.

References INNER, and LEFT.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom().

2729  {
2730  switch (joinType) {
2731  case COMMA:
2732  case INNER:
2733  case CROSS:
2734  return JoinRelType.INNER;
2735  case FULL:
2736  return JoinRelType.FULL;
2737  case LEFT:
2738  return JoinRelType.LEFT;
2739  case RIGHT:
2740  return JoinRelType.RIGHT;
2741  default:
2742  throw Util.unexpected(joinType);
2743  }
2744  }
+ Here is the caller graph for this function:

◆ convertLiteralInValuesList()

RexLiteral org.apache.calcite.sql2rel.SqlToRelConverter.convertLiteralInValuesList ( SqlNode  sqlNode,
Blackboard  bb,
RelDataType  rowType,
int  iField 
)
inlineprivate

Definition at line 1626 of file SqlToRelConverter.java.

References field(), and run_benchmark_import.type.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertRowValues().

1627  {
1628  if (!(sqlNode instanceof SqlLiteral)) {
1629  return null;
1630  }
1631  RelDataTypeField field = rowType.getFieldList().get(iField);
1632  RelDataType type = field.getType();
1633  if (type.isStruct()) {
1634  // null literals for weird stuff like UDT's need
1635  // special handling during type flattening, so
1636  // don't use LogicalValues for those
1637  return null;
1638  }
1639 
1640  RexNode literalExpr = exprConverter.convertLiteral(bb, (SqlLiteral) sqlNode);
1641 
1642  if (!(literalExpr instanceof RexLiteral)) {
1643  assert literalExpr.isA(SqlKind.CAST);
1644  RexNode child = ((RexCall) literalExpr).getOperands().get(0);
1645  assert RexLiteral.isNullLiteral(child);
1646 
1647  // NOTE jvs 22-Nov-2006: we preserve type info
1648  // in LogicalValues digest, so it's OK to lose it here
1649  return (RexLiteral) child;
1650  }
1651 
1652  RexLiteral literal = (RexLiteral) literalExpr;
1653 
1654  Comparable value = literal.getValue();
1655 
1656  if (SqlTypeUtil.isExactNumeric(type) && SqlTypeUtil.hasScale(type)) {
1657  BigDecimal roundedValue =
1658  NumberUtil.rescaleBigDecimal((BigDecimal) value, type.getScale());
1659  return rexBuilder.makeExactLiteral(roundedValue, type);
1660  }
1661 
1662  if ((value instanceof NlsString) && (type.getSqlTypeName() == SqlTypeName.CHAR)) {
1663  // pad fixed character type
1664  NlsString unpadded = (NlsString) value;
1665  return rexBuilder.makeCharLiteral(
1666  new NlsString(Spaces.padRight(unpadded.getValue(), type.getPrecision()),
1667  unpadded.getCharsetName(),
1668  unpadded.getCollation()));
1669  }
1670  return literal;
1671  }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertMatchRecognize()

void org.apache.calcite.sql2rel.SqlToRelConverter.convertMatchRecognize ( Blackboard  bb,
SqlCall  call 
)
inlineprotected

Definition at line 2136 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom(), org.apache.calcite.sql2rel.SqlToRelConverter.createBlackboard(), org.apache.calcite.sql2rel.SqlToRelConverter.desc(), org.apache.calcite.sql2rel.SqlToRelConverter.replaceSubQueries(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root, org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setPatternVarRef(), and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setRoot().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom().

2136  {
2137  final SqlMatchRecognize matchRecognize = (SqlMatchRecognize) call;
2138  final SqlValidatorNamespace ns = validator.getNamespace(matchRecognize);
2139  final SqlValidatorScope scope = validator.getMatchRecognizeScope(matchRecognize);
2140 
2141  final Blackboard matchBb = createBlackboard(scope, null, false);
2142  final RelDataType rowType = ns.getRowType();
2143  // convert inner query, could be a table name or a derived table
2144  SqlNode expr = matchRecognize.getTableRef();
2145  convertFrom(matchBb, expr);
2146  final RelNode input = matchBb.root;
2147 
2148  // PARTITION BY
2149  final SqlNodeList partitionList = matchRecognize.getPartitionList();
2150  final ImmutableBitSet.Builder partitionKeys = ImmutableBitSet.builder();
2151  for (SqlNode partition : partitionList) {
2152  RexNode e = matchBb.convertExpression(partition);
2153  partitionKeys.set(((RexInputRef) e).getIndex());
2154  }
2155 
2156  // ORDER BY
2157  final SqlNodeList orderList = matchRecognize.getOrderList();
2158  final List<RelFieldCollation> orderKeys = new ArrayList<>();
2159  for (SqlNode order : orderList) {
2160  final RelFieldCollation.Direction direction;
2161  switch (order.getKind()) {
2162  case DESCENDING:
2163  direction = RelFieldCollation.Direction.DESCENDING;
2164  order = ((SqlCall) order).operand(0);
2165  break;
2166  case NULLS_FIRST:
2167  case NULLS_LAST:
2168  throw new AssertionError();
2169  default:
2170  direction = RelFieldCollation.Direction.ASCENDING;
2171  break;
2172  }
2173  final RelFieldCollation.NullDirection nullDirection =
2174  validator.config().defaultNullCollation().last(desc(direction))
2175  ? RelFieldCollation.NullDirection.LAST
2176  : RelFieldCollation.NullDirection.FIRST;
2177  RexNode e = matchBb.convertExpression(order);
2178  orderKeys.add(new RelFieldCollation(
2179  ((RexInputRef) e).getIndex(), direction, nullDirection));
2180  }
2181  final RelCollation orders = cluster.traitSet().canonize(RelCollations.of(orderKeys));
2182 
2183  // convert pattern
2184  final Set<String> patternVarsSet = new HashSet<>();
2185  SqlNode pattern = matchRecognize.getPattern();
2186  final SqlBasicVisitor<RexNode> patternVarVisitor = new SqlBasicVisitor<RexNode>() {
2187  @Override
2188  public RexNode visit(SqlCall call) {
2189  List<SqlNode> operands = call.getOperandList();
2190  List<RexNode> newOperands = new ArrayList<>();
2191  for (SqlNode node : operands) {
2192  newOperands.add(node.accept(this));
2193  }
2194  return rexBuilder.makeCall(
2195  validator.getUnknownType(), call.getOperator(), newOperands);
2196  }
2197 
2198  @Override
2199  public RexNode visit(SqlIdentifier id) {
2200  assert id.isSimple();
2201  patternVarsSet.add(id.getSimple());
2202  return rexBuilder.makeLiteral(id.getSimple());
2203  }
2204 
2205  @Override
2206  public RexNode visit(SqlLiteral literal) {
2207  if (literal instanceof SqlNumericLiteral) {
2208  return rexBuilder.makeExactLiteral(BigDecimal.valueOf(literal.intValue(true)));
2209  } else {
2210  return rexBuilder.makeLiteral(literal.booleanValue());
2211  }
2212  }
2213  };
2214  final RexNode patternNode = pattern.accept(patternVarVisitor);
2215 
2216  SqlLiteral interval = matchRecognize.getInterval();
2217  RexNode intervalNode = null;
2218  if (interval != null) {
2219  intervalNode = matchBb.convertLiteral(interval);
2220  }
2221 
2222  // convert subset
2223  final SqlNodeList subsets = matchRecognize.getSubsetList();
2224  final Map<String, TreeSet<String>> subsetMap = new HashMap<>();
2225  for (SqlNode node : subsets) {
2226  List<SqlNode> operands = ((SqlCall) node).getOperandList();
2227  SqlIdentifier left = (SqlIdentifier) operands.get(0);
2228  patternVarsSet.add(left.getSimple());
2229  SqlNodeList rights = (SqlNodeList) operands.get(1);
2230  final TreeSet<String> list = new TreeSet<>();
2231  for (SqlNode right : rights) {
2232  assert right instanceof SqlIdentifier;
2233  list.add(((SqlIdentifier) right).getSimple());
2234  }
2235  subsetMap.put(left.getSimple(), list);
2236  }
2237 
2238  SqlNode afterMatch = matchRecognize.getAfter();
2239  if (afterMatch == null) {
2240  afterMatch =
2241  SqlMatchRecognize.AfterOption.SKIP_TO_NEXT_ROW.symbol(SqlParserPos.ZERO);
2242  }
2243 
2244  final RexNode after;
2245  if (afterMatch instanceof SqlCall) {
2246  List<SqlNode> operands = ((SqlCall) afterMatch).getOperandList();
2247  SqlOperator operator = ((SqlCall) afterMatch).getOperator();
2248  assert operands.size() == 1;
2249  SqlIdentifier id = (SqlIdentifier) operands.get(0);
2250  assert patternVarsSet.contains(id.getSimple())
2251  : id.getSimple()
2252  + " not defined in pattern";
2253  RexNode rex = rexBuilder.makeLiteral(id.getSimple());
2254  after = rexBuilder.makeCall(
2255  validator.getUnknownType(), operator, ImmutableList.of(rex));
2256  } else {
2257  after = matchBb.convertExpression(afterMatch);
2258  }
2259 
2260  matchBb.setPatternVarRef(true);
2261 
2262  // convert measures
2263  final ImmutableMap.Builder<String, RexNode> measureNodes = ImmutableMap.builder();
2264  for (SqlNode measure : matchRecognize.getMeasureList()) {
2265  List<SqlNode> operands = ((SqlCall) measure).getOperandList();
2266  String alias = ((SqlIdentifier) operands.get(1)).getSimple();
2267  RexNode rex = matchBb.convertExpression(operands.get(0));
2268  measureNodes.put(alias, rex);
2269  }
2270 
2271  // convert definitions
2272  final ImmutableMap.Builder<String, RexNode> definitionNodes = ImmutableMap.builder();
2273  for (SqlNode def : matchRecognize.getPatternDefList()) {
2274  replaceSubQueries(matchBb, def, RelOptUtil.Logic.UNKNOWN_AS_FALSE);
2275  List<SqlNode> operands = ((SqlCall) def).getOperandList();
2276  String alias = ((SqlIdentifier) operands.get(1)).getSimple();
2277  RexNode rex = matchBb.convertExpression(operands.get(0));
2278  definitionNodes.put(alias, rex);
2279  }
2280 
2281  final SqlLiteral rowsPerMatch = matchRecognize.getRowsPerMatch();
2282  final boolean allRows = rowsPerMatch != null
2283  && rowsPerMatch.getValue() == SqlMatchRecognize.RowsPerMatchOption.ALL_ROWS;
2284 
2285  matchBb.setPatternVarRef(false);
2286 
2287  final RelFactories.MatchFactory factory = RelFactories.DEFAULT_MATCH_FACTORY;
2288  final RelNode rel = factory.createMatch(input,
2289  patternNode,
2290  rowType,
2291  matchRecognize.getStrictStart().booleanValue(),
2292  matchRecognize.getStrictEnd().booleanValue(),
2293  definitionNodes.build(),
2294  measureNodes.build(),
2295  after,
2296  subsetMap,
2297  allRows,
2298  partitionKeys.build(),
2299  orders,
2300  intervalNode);
2301  bb.setRoot(rel, false);
2302  }
void convertFrom(Blackboard bb, SqlNode from)
void replaceSubQueries(final Blackboard bb, final SqlNode expr, RelOptUtil.Logic logic)
static boolean desc(RelFieldCollation.Direction direction)
Blackboard createBlackboard(SqlValidatorScope scope, Map< String, RexNode > nameToNodeMap, boolean top)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertMerge()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.convertMerge ( SqlMerge  call)
inlineprivate

Definition at line 3676 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.catalogReader, org.apache.calcite.sql2rel.SqlToRelConverter.convertInsert(), org.apache.calcite.sql2rel.SqlToRelConverter.convertSelect(), field(), org.apache.calcite.sql2rel.SqlToRelConverter.getTargetTable(), and join().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryRecursive().

3676  {
3677  RelOptTable targetTable = getTargetTable(call);
3678 
3679  // convert update column list from SqlIdentifier to String
3680  final List<String> targetColumnNameList = new ArrayList<>();
3681  final RelDataType targetRowType = targetTable.getRowType();
3682  SqlUpdate updateCall = call.getUpdateCall();
3683  if (updateCall != null) {
3684  for (SqlNode targetColumn : updateCall.getTargetColumnList()) {
3685  SqlIdentifier id = (SqlIdentifier) targetColumn;
3686  RelDataTypeField field = SqlValidatorUtil.getTargetField(
3687  targetRowType, typeFactory, id, catalogReader, targetTable);
3688  assert field != null : "column " + id.toString() + " not found";
3689  targetColumnNameList.add(field.getName());
3690  }
3691  }
3692 
3693  // replace the projection of the source select with a
3694  // projection that contains the following:
3695  // 1) the expressions corresponding to the new insert row (if there is
3696  // an insert)
3697  // 2) all columns from the target table (if there is an update)
3698  // 3) the set expressions in the update call (if there is an update)
3699 
3700  // first, convert the merge's source select to construct the columns
3701  // from the target table and the set expressions in the update call
3702  RelNode mergeSourceRel = convertSelect(call.getSourceSelect(), false);
3703 
3704  // then, convert the insert statement so we can get the insert
3705  // values expressions
3706  SqlInsert insertCall = call.getInsertCall();
3707  int nLevel1Exprs = 0;
3708  List<RexNode> level1InsertExprs = null;
3709  List<RexNode> level2InsertExprs = null;
3710  if (insertCall != null) {
3711  RelNode insertRel = convertInsert(insertCall);
3712 
3713  // if there are 2 level of projections in the insert source, combine
3714  // them into a single project; level1 refers to the topmost project;
3715  // the level1 projection contains references to the level2
3716  // expressions, except in the case where no target expression was
3717  // provided, in which case, the expression is the default value for
3718  // the column; or if the expressions directly map to the source
3719  // table
3720  level1InsertExprs = ((LogicalProject) insertRel.getInput(0)).getProjects();
3721  if (insertRel.getInput(0).getInput(0) instanceof LogicalProject) {
3722  level2InsertExprs =
3723  ((LogicalProject) insertRel.getInput(0).getInput(0)).getProjects();
3724  }
3725  nLevel1Exprs = level1InsertExprs.size();
3726  }
3727 
3728  LogicalJoin join = (LogicalJoin) mergeSourceRel.getInput(0);
3729  int nSourceFields = join.getLeft().getRowType().getFieldCount();
3730  final List<RexNode> projects = new ArrayList<>();
3731  for (int level1Idx = 0; level1Idx < nLevel1Exprs; level1Idx++) {
3732  if ((level2InsertExprs != null)
3733  && (level1InsertExprs.get(level1Idx) instanceof RexInputRef)) {
3734  int level2Idx = ((RexInputRef) level1InsertExprs.get(level1Idx)).getIndex();
3735  projects.add(level2InsertExprs.get(level2Idx));
3736  } else {
3737  projects.add(level1InsertExprs.get(level1Idx));
3738  }
3739  }
3740  if (updateCall != null) {
3741  final LogicalProject project = (LogicalProject) mergeSourceRel;
3742  projects.addAll(Util.skip(project.getProjects(), nSourceFields));
3743  }
3744 
3745  relBuilder.push(join).project(projects);
3746 
3747  return LogicalTableModify.create(targetTable,
3748  catalogReader,
3749  relBuilder.build(),
3750  LogicalTableModify.Operation.MERGE,
3751  targetColumnNameList,
3752  null,
3753  false);
3754  }
std::string join(T const &container, std::string const &delim)
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
RelNode convertSelect(SqlSelect select, boolean top)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertMultisets()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.convertMultisets ( final List< SqlNode >  operands,
Blackboard  bb 
)
inlineprivate

Definition at line 3851 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.convertQuery(), org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryOrInList(), org.apache.calcite.sql2rel.SqlToRelConverter.createBlackboard(), and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.scope.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertRowConstructor(), and org.apache.calcite.sql2rel.SqlToRelConverter.substituteSubQuery().

3851  {
3852  // NOTE: Wael 2/04/05: this implementation is not the most efficient in
3853  // terms of planning since it generates XOs that can be reduced.
3854  final List<Object> joinList = new ArrayList<>();
3855  List<SqlNode> lastList = new ArrayList<>();
3856  for (int i = 0; i < operands.size(); i++) {
3857  SqlNode operand = operands.get(i);
3858  if (!(operand instanceof SqlCall)) {
3859  lastList.add(operand);
3860  continue;
3861  }
3862 
3863  final SqlCall call = (SqlCall) operand;
3864  final RelNode input;
3865  switch (call.getKind()) {
3866  case MULTISET_VALUE_CONSTRUCTOR:
3867  case ARRAY_VALUE_CONSTRUCTOR:
3868  final SqlNodeList list =
3869  new SqlNodeList(call.getOperandList(), call.getParserPosition());
3870  CollectNamespace nss = (CollectNamespace) validator.getNamespace(call);
3871  Blackboard usedBb;
3872  if (null != nss) {
3873  usedBb = createBlackboard(nss.getScope(), null, false);
3874  } else {
3875  usedBb = createBlackboard(new ListScope(bb.scope) {
3876  public SqlNode getNode() {
3877  return call;
3878  }
3879  }, null, false);
3880  }
3881  RelDataType multisetType = validator.getValidatedNodeType(call);
3882  ((SqlValidatorImpl) validator)
3883  .setValidatedNodeType(list, multisetType.getComponentType());
3884  input = convertQueryOrInList(usedBb, list, null);
3885  break;
3886  case MULTISET_QUERY_CONSTRUCTOR:
3887  case ARRAY_QUERY_CONSTRUCTOR:
3888  final RelRoot root = convertQuery(call.operand(0), false, true);
3889  input = root.rel;
3890  break;
3891  default:
3892  lastList.add(operand);
3893  continue;
3894  }
3895 
3896  if (lastList.size() > 0) {
3897  joinList.add(lastList);
3898  }
3899  lastList = new ArrayList<>();
3900  Collect collect = new Collect(cluster,
3901  cluster.traitSetOf(Convention.NONE),
3902  input,
3903  validator.deriveAlias(call, i));
3904  joinList.add(collect);
3905  }
3906 
3907  if (joinList.size() == 0) {
3908  joinList.add(lastList);
3909  }
3910 
3911  for (int i = 0; i < joinList.size(); i++) {
3912  Object o = joinList.get(i);
3913  if (o instanceof List) {
3914  @SuppressWarnings("unchecked")
3915  List<SqlNode> projectList = (List<SqlNode>) o;
3916  final List<RexNode> selectList = new ArrayList<>();
3917  final List<String> fieldNameList = new ArrayList<>();
3918  for (int j = 0; j < projectList.size(); j++) {
3919  SqlNode operand = projectList.get(j);
3920  selectList.add(bb.convertExpression(operand));
3921 
3922  // REVIEW angel 5-June-2005: Use deriveAliasFromOrdinal
3923  // instead of deriveAlias to match field names from
3924  // SqlRowOperator. Otherwise, get error Type
3925  // 'RecordType(INTEGER EMPNO)' has no field 'EXPR$0' when
3926  // doing select * from unnest( select multiset[empno]
3927  // from sales.emps);
3928 
3929  fieldNameList.add(SqlUtil.deriveAliasFromOrdinal(j));
3930  }
3931 
3932  relBuilder.push(LogicalValues.createOneRow(cluster))
3933  .projectNamed(selectList, fieldNameList, true);
3934 
3935  joinList.set(i, relBuilder.build());
3936  }
3937  }
3938 
3939  RelNode ret = (RelNode) joinList.get(0);
3940  for (int i = 1; i < joinList.size(); i++) {
3941  RelNode relNode = (RelNode) joinList.get(i);
3942  ret = RelFactories.DEFAULT_JOIN_FACTORY.createJoin(ret,
3943  relNode,
3944  ImmutableList.of(),
3945  rexBuilder.makeLiteral(true),
3946  ImmutableSet.of(),
3947  JoinRelType.INNER,
3948  false);
3949  }
3950  return ret;
3951  }
RelNode convertQueryOrInList(Blackboard bb, SqlNode seek, RelDataType targetRowType)
Blackboard createBlackboard(SqlValidatorScope scope, Map< String, RexNode > nameToNodeMap, boolean top)
RelRoot convertQuery(SqlNode query, final boolean needsValidation, final boolean top)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertNonCorrelatedSubQuery()

boolean org.apache.calcite.sql2rel.SqlToRelConverter.convertNonCorrelatedSubQuery ( SubQuery  subQuery,
Blackboard  bb,
RelNode  converted,
boolean  isExists 
)
inlineprivate

Determines if a sub-query is non-correlated and if so, converts it to a constant.

Parameters
subQuerythe call that references the sub-query
bbblackboard used to convert the sub-query
convertedRelNode tree corresponding to the sub-query
isExiststrue if the sub-query is part of an EXISTS expression
Returns
Whether the sub-query can be converted to a constant

Definition at line 1350 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.config, and org.apache.calcite.sql2rel.SqlToRelConverter.isSubQueryNonCorrelated().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.substituteSubQuery().

1351  {
1352  SqlCall call = (SqlBasicCall) subQuery.node;
1353  if (subQueryConverter.canConvertSubQuery()
1354  && isSubQueryNonCorrelated(converted, bb)) {
1355  // First check if the sub-query has already been converted
1356  // because it's a nested sub-query. If so, don't re-evaluate
1357  // it again.
1358  RexNode constExpr = mapConvertedNonCorrSubqs.get(call);
1359  if (constExpr == null) {
1360  constExpr = subQueryConverter.convertSubQuery(
1361  call, this, isExists, config.isExplain());
1362  }
1363  if (constExpr != null) {
1364  subQuery.expr = constExpr;
1365  mapConvertedNonCorrSubqs.put(call, constExpr);
1366  return true;
1367  }
1368  }
1369  return false;
1370  }
final Map< SqlNode, RexNode > mapConvertedNonCorrSubqs
boolean isSubQueryNonCorrelated(RelNode subq, Blackboard bb)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertOrder()

void org.apache.calcite.sql2rel.SqlToRelConverter.convertOrder ( SqlSelect  select,
Blackboard  bb,
RelCollation  collation,
List< SqlNode >  orderExprList,
SqlNode  offset,
SqlNode  fetch 
)
inlineprotected

Converts a query's ORDER BY clause, if any.

Ignores the ORDER BY clause if the query is not top-level and FETCH or OFFSET are not present.

Parameters
selectQuery
bbBlackboard
collationCollation list
orderExprListMethod populates this list with orderBy expressions not present in selectList
offsetExpression for number of rows to discard before returning first row
fetchExpression for number of rows to fetch

Definition at line 792 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.convertExpression(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root, org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setRoot(), and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.top.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertSelectImpl().

797  {
798  if (!bb.top || select.getOrderList() == null
799  || select.getOrderList().getList().isEmpty()) {
800  assert !bb.top || collation.getFieldCollations().isEmpty();
801  if ((offset == null
802  || (offset instanceof SqlLiteral
803  && ((SqlLiteral) offset)
804  .bigDecimalValue()
805  .equals(BigDecimal.ZERO)))
806  && fetch == null) {
807  return;
808  }
809  }
810 
811  // Create a sorter using the previously constructed collations.
812  bb.setRoot(LogicalSort.create(bb.root,
813  collation,
814  offset == null ? null : convertExpression(offset),
815  fetch == null ? null : convertExpression(fetch)),
816  false);
817 
818  // If extra expressions were added to the project list for sorting,
819  // add another project to remove them. But make the collation empty, because
820  // we can't represent the real collation.
821  //
822  // If it is the top node, use the real collation, but don't trim fields.
823  if (orderExprList.size() > 0 && !bb.top) {
824  final List<RexNode> exprs = new ArrayList<>();
825  final RelDataType rowType = bb.root.getRowType();
826  final int fieldCount = rowType.getFieldCount() - orderExprList.size();
827  for (int i = 0; i < fieldCount; i++) {
828  exprs.add(rexBuilder.makeInputRef(bb.root, i));
829  }
830  bb.setRoot(LogicalProject.create(bb.root,
831  ImmutableList.of(),
832  exprs,
833  rowType.getFieldNames().subList(0, fieldCount)),
834  false);
835  }
836  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertOrderItem()

RelFieldCollation org.apache.calcite.sql2rel.SqlToRelConverter.convertOrderItem ( SqlSelect  select,
SqlNode  orderItem,
List< SqlNode >  extraExprs,
RelFieldCollation.Direction  direction,
RelFieldCollation.NullDirection  nullDirection 
)
inlineprotected

Definition at line 3128 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.desc().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.gatherOrderExprs().

3132  {
3133  assert select != null;
3134  // Handle DESC keyword, e.g. 'select a, b from t order by a desc'.
3135  switch (orderItem.getKind()) {
3136  case DESCENDING:
3137  return convertOrderItem(select,
3138  ((SqlCall) orderItem).operand(0),
3139  extraExprs,
3140  RelFieldCollation.Direction.DESCENDING,
3141  nullDirection);
3142  case NULLS_FIRST:
3143  return convertOrderItem(select,
3144  ((SqlCall) orderItem).operand(0),
3145  extraExprs,
3146  direction,
3147  RelFieldCollation.NullDirection.FIRST);
3148  case NULLS_LAST:
3149  return convertOrderItem(select,
3150  ((SqlCall) orderItem).operand(0),
3151  extraExprs,
3152  direction,
3153  RelFieldCollation.NullDirection.LAST);
3154  }
3155 
3156  SqlNode converted = validator.expandOrderExpr(select, orderItem);
3157 
3158  switch (nullDirection) {
3159  case UNSPECIFIED:
3160  nullDirection = validator.config().defaultNullCollation().last(desc(direction))
3161  ? RelFieldCollation.NullDirection.LAST
3162  : RelFieldCollation.NullDirection.FIRST;
3163  }
3164 
3165  // Scan the select list and order exprs for an identical expression.
3166  final SelectScope selectScope = validator.getRawSelectScope(select);
3167  int ordinal = -1;
3168  for (SqlNode selectItem : selectScope.getExpandedSelectList()) {
3169  ++ordinal;
3170  if (converted.equalsDeep(stripAs(selectItem), Litmus.IGNORE)) {
3171  return new RelFieldCollation(ordinal, direction, nullDirection);
3172  }
3173  }
3174 
3175  for (SqlNode extraExpr : extraExprs) {
3176  ++ordinal;
3177  if (converted.equalsDeep(extraExpr, Litmus.IGNORE)) {
3178  return new RelFieldCollation(ordinal, direction, nullDirection);
3179  }
3180  }
3181 
3182  // TODO: handle collation sequence
3183  // TODO: flag expressions as non-standard
3184 
3185  extraExprs.add(converted);
3186  return new RelFieldCollation(ordinal + 1, direction, nullDirection);
3187  }
static boolean desc(RelFieldCollation.Direction direction)
RelFieldCollation convertOrderItem(SqlSelect select, SqlNode orderItem, List< SqlNode > extraExprs, RelFieldCollation.Direction direction, RelFieldCollation.NullDirection nullDirection)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertOver()

RexNode org.apache.calcite.sql2rel.SqlToRelConverter.convertOver ( Blackboard  bb,
SqlNode  node 
)
inlineprivate

Definition at line 1835 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.scope, and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.window.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.lookupExp().

1835  {
1836  SqlCall call = (SqlCall) node;
1837  SqlCall aggCall = call.operand(0);
1838  boolean ignoreNulls = false;
1839  switch (aggCall.getKind()) {
1840  case IGNORE_NULLS:
1841  ignoreNulls = true;
1842  // fall through
1843  case RESPECT_NULLS:
1844  aggCall = aggCall.operand(0);
1845  }
1846 
1847  SqlNode windowOrRef = call.operand(1);
1848  final SqlWindow window = validator.resolveWindow(windowOrRef, bb.scope);
1849 
1850  SqlNode sqlLowerBound = window.getLowerBound();
1851  SqlNode sqlUpperBound = window.getUpperBound();
1852  boolean rows = window.isRows();
1853  SqlNodeList orderList = window.getOrderList();
1854 
1855  if (!aggCall.getOperator().allowsFraming()) {
1856  // If the operator does not allow framing, bracketing is implicitly
1857  // everything up to the current row.
1858  sqlLowerBound = SqlWindow.createUnboundedPreceding(SqlParserPos.ZERO);
1859  sqlUpperBound = SqlWindow.createCurrentRow(SqlParserPos.ZERO);
1860  if (aggCall.getKind() == SqlKind.ROW_NUMBER) {
1861  // ROW_NUMBER() expects specific kind of framing.
1862  rows = true;
1863  }
1864  } else if (orderList.size() == 0) {
1865  // Without ORDER BY, there must be no bracketing.
1866  sqlLowerBound = SqlWindow.createUnboundedPreceding(SqlParserPos.ZERO);
1867  sqlUpperBound = SqlWindow.createUnboundedFollowing(SqlParserPos.ZERO);
1868  } else if (sqlLowerBound == null && sqlUpperBound == null) {
1869  sqlLowerBound = SqlWindow.createUnboundedPreceding(SqlParserPos.ZERO);
1870  sqlUpperBound = SqlWindow.createCurrentRow(SqlParserPos.ZERO);
1871  } else if (sqlUpperBound == null) {
1872  sqlUpperBound = SqlWindow.createCurrentRow(SqlParserPos.ZERO);
1873  } else if (sqlLowerBound == null) {
1874  sqlLowerBound = SqlWindow.createCurrentRow(SqlParserPos.ZERO);
1875  }
1876  final SqlNodeList partitionList = window.getPartitionList();
1877  final ImmutableList.Builder<RexNode> partitionKeys = ImmutableList.builder();
1878  for (SqlNode partition : partitionList) {
1879  partitionKeys.add(bb.convertExpression(partition));
1880  }
1881  final RexNode lowerBound = bb.convertExpression(sqlLowerBound);
1882  final RexNode upperBound = bb.convertExpression(sqlUpperBound);
1883  if (orderList.size() == 0 && !rows) {
1884  // A logical range requires an ORDER BY clause. Use the implicit
1885  // ordering of this relation. There must be one, otherwise it would
1886  // have failed validation.
1887  orderList = bb.scope.getOrderList();
1888  if (orderList == null) {
1889  throw new AssertionError("Relation should have sort key for implicit ORDER BY");
1890  }
1891  }
1892 
1893  final ImmutableList.Builder<RexFieldCollation> orderKeys = ImmutableList.builder();
1894  for (SqlNode order : orderList) {
1895  orderKeys.add(bb.convertSortExpression(order,
1896  RelFieldCollation.Direction.ASCENDING,
1897  RelFieldCollation.NullDirection.UNSPECIFIED));
1898  }
1899 
1900  try {
1901  Preconditions.checkArgument(bb.window == null, "already in window agg mode");
1902  bb.window = window;
1903  RexNode rexAgg = exprConverter.convertCall(bb, aggCall);
1904  rexAgg = rexBuilder.ensureType(validator.getValidatedNodeType(call), rexAgg, false);
1905 
1906  // Walk over the tree and apply 'over' to all agg functions. This is
1907  // necessary because the returned expression is not necessarily a call
1908  // to an agg function. For example, AVG(x) becomes SUM(x) / COUNT(x).
1909 
1910  final SqlLiteral q = aggCall.getFunctionQuantifier();
1911  final boolean isDistinct = q != null && q.getValue() == SqlSelectKeyword.DISTINCT;
1912 
1913  final RexShuttle visitor = new HistogramShuttle(partitionKeys.build(),
1914  orderKeys.build(),
1915  RexWindowBounds.create(sqlLowerBound, lowerBound),
1916  RexWindowBounds.create(sqlUpperBound, upperBound),
1917  rows,
1918  window.isAllowPartial(),
1919  isDistinct,
1920  ignoreNulls);
1921  return rexAgg.accept(visitor);
1922  } finally {
1923  bb.window = null;
1924  }
1925  }
+ Here is the caller graph for this function:

◆ convertQuery()

RelRoot org.apache.calcite.sql2rel.SqlToRelConverter.convertQuery ( SqlNode  query,
final boolean  needsValidation,
final boolean  top 
)
inline

Converts an unvalidated query's parse tree into a relational expression.

Parameters
queryQuery to convert
needsValidationWhether to validate the query before converting; false if the query has already been validated.
topWhether the query is top-level, say if its result will become a JDBC result set; false if the query will be part of a view.

Definition at line 555 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.checkConvertedType(), org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryRecursive(), org.apache.calcite.sql2rel.SqlToRelConverter.isOrdered(), org.apache.calcite.sql2rel.SqlToRelConverter.isStream(), org.apache.calcite.sql2rel.SqlToRelConverter.requiredCollation(), and run_benchmark_import.result.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertCollectionTable(), org.apache.calcite.sql2rel.SqlToRelConverter.convertCursor(), org.apache.calcite.sql2rel.SqlToRelConverter.convertMultisets(), and org.apache.calcite.sql2rel.SqlToRelConverter.convertWith().

556  {
557  if (needsValidation) {
558  query = validator.validate(query);
559  }
560 
561  RelNode result = convertQueryRecursive(query, top, null).rel;
562  if (top) {
563  if (isStream(query)) {
564  result = new LogicalDelta(cluster, result.getTraitSet(), result);
565  }
566  }
567  RelCollation collation = RelCollations.EMPTY;
568  if (!query.isA(SqlKind.DML)) {
569  if (isOrdered(query)) {
570  collation = requiredCollation(result);
571  }
572  }
573  checkConvertedType(query, result);
574 
575  if (SQL2REL_LOGGER.isDebugEnabled()) {
576  SQL2REL_LOGGER.debug(RelOptUtil.dumpPlan("Plan after converting SqlNode to RelNode",
577  result,
578  SqlExplainFormat.TEXT,
579  SqlExplainLevel.EXPPLAN_ATTRIBUTES));
580  }
581 
582  final RelDataType validatedRowType = validator.getValidatedNodeType(query);
583  List<RelHint> hints = new ArrayList<>();
584  if (query.getKind() == SqlKind.SELECT) {
585  final SqlSelect select = (SqlSelect) query;
586  if (select.hasHints()) {
587  hints = SqlUtil.getRelHint(hintStrategies, select.getHints());
588  }
589  }
590  // propagate the hints.
591  result = RelOptUtil.propagateRelHints(result, false);
592  return RelRoot.of(result, validatedRowType, query.getKind())
593  .withCollation(collation)
594  .withHints(hints);
595  }
void checkConvertedType(SqlNode query, RelNode result)
RelRoot convertQueryRecursive(SqlNode query, boolean top, RelDataType targetRowType)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertQueryOrInList()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryOrInList ( Blackboard  bb,
SqlNode  seek,
RelDataType  targetRowType 
)
inlineprivate

Definition at line 1536 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryRecursive(), and org.apache.calcite.sql2rel.SqlToRelConverter.convertRowValues().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertExists(), org.apache.calcite.sql2rel.SqlToRelConverter.convertMultisets(), and org.apache.calcite.sql2rel.SqlToRelConverter.substituteSubQuery().

1537  {
1538  // NOTE: Once we start accepting single-row queries as row constructors,
1539  // there will be an ambiguity here for a case like X IN ((SELECT Y FROM
1540  // Z)). The SQL standard resolves the ambiguity by saying that a lone
1541  // select should be interpreted as a table expression, not a row
1542  // expression. The semantic difference is that a table expression can
1543  // return multiple rows.
1544  if (seek instanceof SqlNodeList) {
1545  return convertRowValues(
1546  bb, seek, ((SqlNodeList) seek).getList(), false, targetRowType);
1547  } else {
1548  return convertQueryRecursive(seek, false, null).project();
1549  }
1550  }
RelNode convertRowValues(Blackboard bb, SqlNode rowList, Collection< SqlNode > rows, boolean allowLiteralsOnly, RelDataType targetRowType)
RelRoot convertQueryRecursive(SqlNode query, boolean top, RelDataType targetRowType)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertQueryRecursive()

RelRoot org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryRecursive ( SqlNode  query,
boolean  top,
RelDataType  targetRowType 
)
inlineprotected

Recursively converts a query to a relational expression.

Parameters
queryQuery
topWhether this query is the top-level query of the statement
targetRowTypeTarget row type, or null
Returns
Relational expression

Definition at line 3229 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.convertDelete(), org.apache.calcite.sql2rel.SqlToRelConverter.convertInsert(), org.apache.calcite.sql2rel.SqlToRelConverter.convertMerge(), org.apache.calcite.sql2rel.SqlToRelConverter.convertSelect(), org.apache.calcite.sql2rel.SqlToRelConverter.convertSetOp(), org.apache.calcite.sql2rel.SqlToRelConverter.convertUpdate(), org.apache.calcite.sql2rel.SqlToRelConverter.convertValues(), and org.apache.calcite.sql2rel.SqlToRelConverter.convertWith().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom(), org.apache.calcite.sql2rel.SqlToRelConverter.convertInsert(), org.apache.calcite.sql2rel.SqlToRelConverter.convertQuery(), org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryOrInList(), org.apache.calcite.sql2rel.SqlToRelConverter.convertSetOp(), and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.lookupExp().

3230  {
3231  final SqlKind kind = query.getKind();
3232  switch (kind) {
3233  case SELECT:
3234  return RelRoot.of(convertSelect((SqlSelect) query, top), kind);
3235  case INSERT:
3236  return RelRoot.of(convertInsert((SqlInsert) query), kind);
3237  case DELETE:
3238  return RelRoot.of(convertDelete((SqlDelete) query), kind);
3239  case UPDATE:
3240  return RelRoot.of(convertUpdate((SqlUpdate) query), kind);
3241  case MERGE:
3242  return RelRoot.of(convertMerge((SqlMerge) query), kind);
3243  case UNION:
3244  case INTERSECT:
3245  case EXCEPT:
3246  return RelRoot.of(convertSetOp((SqlCall) query), kind);
3247  case WITH:
3248  return convertWith((SqlWith) query, top);
3249  case VALUES:
3250  return RelRoot.of(convertValues((SqlCall) query, targetRowType), kind);
3251  default:
3252  throw new AssertionError("not a query: " + query);
3253  }
3254  }
RelRoot convertWith(SqlWith with, boolean top)
RelNode convertValues(SqlCall values, RelDataType targetRowType)
RelNode convertSelect(SqlSelect select, boolean top)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertRowConstructor()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.convertRowConstructor ( Blackboard  bb,
SqlCall  rowConstructor 
)
inlineprivate

Converts a row constructor into a relational expression.

Parameters
bbBlackboard
rowConstructorRow constructor expression
Returns
Relational expression which returns a single row.

Definition at line 3834 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.convertMultisets(), and org.apache.calcite.sql2rel.SqlToRelConverter.isRowConstructor().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertRowValues().

3834  {
3835  Preconditions.checkArgument(isRowConstructor(rowConstructor));
3836  final List<SqlNode> operands = rowConstructor.getOperandList();
3837  return convertMultisets(operands, bb);
3838  }
RelNode convertMultisets(final List< SqlNode > operands, Blackboard bb)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertRowValues()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.convertRowValues ( Blackboard  bb,
SqlNode  rowList,
Collection< SqlNode >  rows,
boolean  allowLiteralsOnly,
RelDataType  targetRowType 
)
inlineprivate

Definition at line 1552 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.config, org.apache.calcite.sql2rel.SqlToRelConverter.convertLiteralInValuesList(), org.apache.calcite.sql2rel.SqlToRelConverter.convertRowConstructor(), and org.apache.calcite.sql2rel.SqlToRelConverter.isRowConstructor().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryOrInList(), and org.apache.calcite.sql2rel.SqlToRelConverter.convertValuesImpl().

1556  {
1557  // NOTE jvs 30-Apr-2006: We combine all rows consisting entirely of
1558  // literals into a single LogicalValues; this gives the optimizer a smaller
1559  // input tree. For everything else (computed expressions, row
1560  // sub-queries), we union each row in as a projection on top of a
1561  // LogicalOneRow.
1562 
1563  final ImmutableList.Builder<ImmutableList<RexLiteral>> tupleList =
1564  ImmutableList.builder();
1565  final RelDataType rowType;
1566  if (targetRowType != null) {
1567  rowType = targetRowType;
1568  } else {
1569  rowType = SqlTypeUtil.promoteToRowType(
1570  typeFactory, validator.getValidatedNodeType(rowList), null);
1571  }
1572 
1573  final List<RelNode> unionInputs = new ArrayList<>();
1574  for (SqlNode node : rows) {
1575  SqlBasicCall call;
1576  if (isRowConstructor(node)) {
1577  call = (SqlBasicCall) node;
1578  ImmutableList.Builder<RexLiteral> tuple = ImmutableList.builder();
1579  for (Ord<SqlNode> operand : Ord.zip(call.operands)) {
1580  RexLiteral rexLiteral =
1581  convertLiteralInValuesList(operand.e, bb, rowType, operand.i);
1582  if ((rexLiteral == null) && allowLiteralsOnly) {
1583  return null;
1584  }
1585  if ((rexLiteral == null) || !config.isCreateValuesRel()) {
1586  // fallback to convertRowConstructor
1587  tuple = null;
1588  break;
1589  }
1590  tuple.add(rexLiteral);
1591  }
1592  if (tuple != null) {
1593  tupleList.add(tuple.build());
1594  continue;
1595  }
1596  } else {
1597  RexLiteral rexLiteral = convertLiteralInValuesList(node, bb, rowType, 0);
1598  if ((rexLiteral != null) && config.isCreateValuesRel()) {
1599  tupleList.add(ImmutableList.of(rexLiteral));
1600  continue;
1601  } else {
1602  if ((rexLiteral == null) && allowLiteralsOnly) {
1603  return null;
1604  }
1605  }
1606 
1607  // convert "1" to "row(1)"
1608  call = (SqlBasicCall) SqlStdOperatorTable.ROW.createCall(SqlParserPos.ZERO, node);
1609  }
1610  unionInputs.add(convertRowConstructor(bb, call));
1611  }
1612  LogicalValues values = LogicalValues.create(cluster, rowType, tupleList.build());
1613  RelNode resultRel;
1614  if (unionInputs.isEmpty()) {
1615  resultRel = values;
1616  } else {
1617  if (!values.getTuples().isEmpty()) {
1618  unionInputs.add(values);
1619  }
1620  resultRel = LogicalUnion.create(unionInputs, true);
1621  }
1622  leaves.put(resultRel, resultRel.getRowType().getFieldCount());
1623  return resultRel;
1624  }
RelNode convertRowConstructor(Blackboard bb, SqlCall rowConstructor)
RexLiteral convertLiteralInValuesList(SqlNode sqlNode, Blackboard bb, RelDataType rowType, int iField)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertSelect()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.convertSelect ( SqlSelect  select,
boolean  top 
)
inline

Converts a SELECT statement's parse tree into a relational expression.

Definition at line 632 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.convertSelectImpl(), org.apache.calcite.sql2rel.SqlToRelConverter.createBlackboard(), and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertDelete(), org.apache.calcite.sql2rel.SqlToRelConverter.convertMerge(), org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryRecursive(), and org.apache.calcite.sql2rel.SqlToRelConverter.convertUpdate().

632  {
633  final SqlValidatorScope selectScope = validator.getWhereScope(select);
634  final Blackboard bb = createBlackboard(selectScope, null, top);
635  convertSelectImpl(bb, select);
636  return bb.root;
637  }
void convertSelectImpl(final Blackboard bb, SqlSelect select)
Blackboard createBlackboard(SqlValidatorScope scope, Map< String, RexNode > nameToNodeMap, boolean top)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertSelectImpl()

void org.apache.calcite.sql2rel.SqlToRelConverter.convertSelectImpl ( final Blackboard  bb,
SqlSelect  select 
)
inlineprotected

Implementation of convertSelect(SqlSelect, boolean); derived class may override.

Definition at line 651 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.convertAgg(), org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom(), org.apache.calcite.sql2rel.SqlToRelConverter.convertOrder(), org.apache.calcite.sql2rel.SqlToRelConverter.convertSelectList(), org.apache.calcite.sql2rel.SqlToRelConverter.convertWhere(), org.apache.calcite.sql2rel.SqlToRelConverter.distinctify(), org.apache.calcite.sql2rel.SqlToRelConverter.gatherOrderExprs(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root, and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setRoot().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertSelect().

651  {
652  convertFrom(bb, select.getFrom());
653  convertWhere(bb, select.getWhere());
654 
655  final List<SqlNode> orderExprList = new ArrayList<>();
656  final List<RelFieldCollation> collationList = new ArrayList<>();
657  gatherOrderExprs(bb, select, select.getOrderList(), orderExprList, collationList);
658  final RelCollation collation =
659  cluster.traitSet().canonize(RelCollations.of(collationList));
660 
661  if (validator.isAggregate(select)) {
662  convertAgg(bb, select, orderExprList);
663  } else {
664  convertSelectList(bb, select, orderExprList);
665  }
666 
667  if (select.isDistinct()) {
668  distinctify(bb, true);
669  }
670 
671  convertOrder(
672  select, bb, collation, orderExprList, select.getOffset(), select.getFetch());
673 
674  if (select.hasHints()) {
675  final List<RelHint> hints = SqlUtil.getRelHint(hintStrategies, select.getHints());
676  // Attach the hints to the first Hintable node we found from the root node.
677  bb.setRoot(bb.root.accept(new RelShuttleImpl() {
678  boolean attached = false;
679 
680  @Override
681  public RelNode visitChild(RelNode parent, int i, RelNode child) {
682  if (parent instanceof Hintable && !attached) {
683  attached = true;
684  return ((Hintable) parent).attachHints(hints);
685  } else {
686  return super.visitChild(parent, i, child);
687  }
688  }
689  }),
690  true);
691  } else {
692  bb.setRoot(bb.root, true);
693  }
694  }
void convertFrom(Blackboard bb, SqlNode from)
void distinctify(Blackboard bb, boolean checkForDupExprs)
void convertAgg(Blackboard bb, SqlSelect select, List< SqlNode > orderExprList)
void gatherOrderExprs(Blackboard bb, SqlSelect select, SqlNodeList orderList, List< SqlNode > extraOrderExprs, List< RelFieldCollation > collationList)
void convertWhere(final Blackboard bb, final SqlNode where)
void convertOrder(SqlSelect select, Blackboard bb, RelCollation collation, List< SqlNode > orderExprList, SqlNode offset, SqlNode fetch)
void convertSelectList(Blackboard bb, SqlSelect select, List< SqlNode > orderList)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertSelectList()

void org.apache.calcite.sql2rel.SqlToRelConverter.convertSelectList ( Blackboard  bb,
SqlSelect  select,
List< SqlNode >  orderList 
)
inlineprivate

Definition at line 3953 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.catalogReader, org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.columnMonotonicities, org.apache.calcite.sql2rel.SqlToRelConverter.deriveAlias(), org.apache.calcite.sql2rel.SqlToRelConverter.extraSelectItems(), org.apache.calcite.sql2rel.SqlToRelConverter.relBuilder, org.apache.calcite.sql2rel.SqlToRelConverter.replaceSubQueries(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root, org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.scope, org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setRoot(), and org.apache.calcite.sql2rel.SqlToRelConverter.validator.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertSelectImpl().

3954  {
3955  SqlNodeList selectList = select.getSelectList();
3956  selectList = validator.expandStar(selectList, select, false);
3957 
3958  replaceSubQueries(bb, selectList, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
3959 
3960  List<String> fieldNames = new ArrayList<>();
3961  final List<RexNode> exprs = new ArrayList<>();
3962  final Collection<String> aliases = new TreeSet<>();
3963 
3964  // Project any system fields. (Must be done before regular select items,
3965  // because offsets may be affected.)
3966  final List<SqlMonotonicity> columnMonotonicityList = new ArrayList<>();
3967  extraSelectItems(bb, select, exprs, fieldNames, aliases, columnMonotonicityList);
3968 
3969  // Project select clause.
3970  int i = -1;
3971  for (SqlNode expr : selectList) {
3972  ++i;
3973  exprs.add(bb.convertExpression(expr));
3974  fieldNames.add(deriveAlias(expr, aliases, i));
3975  }
3976 
3977  // Project extra fields for sorting.
3978  for (SqlNode expr : orderList) {
3979  ++i;
3980  SqlNode expr2 = validator.expandOrderExpr(select, expr);
3981  exprs.add(bb.convertExpression(expr2));
3982  fieldNames.add(deriveAlias(expr, aliases, i));
3983  }
3984 
3985  fieldNames = SqlValidatorUtil.uniquify(
3986  fieldNames, catalogReader.nameMatcher().isCaseSensitive());
3987 
3988  relBuilder.push(bb.root).projectNamed(exprs, fieldNames, true);
3989  bb.setRoot(relBuilder.build(), false);
3990 
3991  assert bb.columnMonotonicities.isEmpty();
3992  bb.columnMonotonicities.addAll(columnMonotonicityList);
3993  for (SqlNode selectItem : selectList) {
3994  bb.columnMonotonicities.add(selectItem.getMonotonicity(bb.scope));
3995  }
3996  }
void extraSelectItems(Blackboard bb, SqlSelect select, List< RexNode > exprList, List< String > nameList, Collection< String > aliasList, List< SqlMonotonicity > columnMonotonicityList)
String deriveAlias(final SqlNode node, Collection< String > aliases, final int ordinal)
void replaceSubQueries(final Blackboard bb, final SqlNode expr, RelOptUtil.Logic logic)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertSetOp()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.convertSetOp ( SqlCall  call)
inlineprotected

Converts a set operation (UNION, INTERSECT, MINUS) into relational expressions.

Parameters
callCall to set operator
Returns
Relational expression

Definition at line 3263 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.all(), and org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryRecursive().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryRecursive().

3263  {
3264  final RelNode left = convertQueryRecursive(call.operand(0), false, null).project();
3265  final RelNode right = convertQueryRecursive(call.operand(1), false, null).project();
3266  switch (call.getKind()) {
3267  case UNION:
3268  return LogicalUnion.create(ImmutableList.of(left, right), all(call));
3269 
3270  case INTERSECT:
3271  return LogicalIntersect.create(ImmutableList.of(left, right), all(call));
3272 
3273  case EXCEPT:
3274  return LogicalMinus.create(ImmutableList.of(left, right), all(call));
3275 
3276  default:
3277  throw Util.unexpected(call.getKind());
3278  }
3279  }
RelRoot convertQueryRecursive(SqlNode query, boolean top, RelDataType targetRowType)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertTemporalTable()

void org.apache.calcite.sql2rel.SqlToRelConverter.convertTemporalTable ( Blackboard  bb,
SqlCall  call 
)
inlineprivate

Definition at line 2392 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root, and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setRoot().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom().

2392  {
2393  final SqlSnapshot snapshot = (SqlSnapshot) call;
2394  final RexNode period = bb.convertExpression(snapshot.getPeriod());
2395 
2396  // convert inner query, could be a table name or a derived table
2397  SqlNode expr = snapshot.getTableRef();
2398  convertFrom(bb, expr);
2399 
2400  final RelNode snapshotRel = relBuilder.push(bb.root).snapshot(period).build();
2401 
2402  bb.setRoot(snapshotRel, false);
2403  }
void convertFrom(Blackboard bb, SqlNode from)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertToSingleValueSubq()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.convertToSingleValueSubq ( SqlNode  query,
RelNode  plan 
)
inline

Converts the RelNode tree for a select statement to a select that produces a single value.

Parameters
querythe query
planthe original RelNode tree corresponding to the statement
Returns
the converted RelNode tree

Definition at line 1380 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.substituteSubQuery().

1380  {
1381  // Check whether query is guaranteed to produce a single value.
1382  if (query instanceof SqlSelect) {
1383  SqlSelect select = (SqlSelect) query;
1384  SqlNodeList selectList = select.getSelectList();
1385  SqlNodeList groupList = select.getGroup();
1386 
1387  if ((selectList.size() == 1) && ((groupList == null) || (groupList.size() == 0))) {
1388  SqlNode selectExpr = selectList.get(0);
1389  if (selectExpr instanceof SqlCall) {
1390  SqlCall selectExprCall = (SqlCall) selectExpr;
1391  if (Util.isSingleValue(selectExprCall)) {
1392  return plan;
1393  }
1394  }
1395 
1396  // If there is a limit with 0 or 1,
1397  // it is ensured to produce a single value
1398  if (select.getFetch() != null && select.getFetch() instanceof SqlNumericLiteral) {
1399  SqlNumericLiteral limitNum = (SqlNumericLiteral) select.getFetch();
1400  if (((BigDecimal) limitNum.getValue()).intValue() < 2) {
1401  return plan;
1402  }
1403  }
1404  }
1405  } else if (query instanceof SqlCall) {
1406  // If the query is (values ...),
1407  // it is necessary to look into the operands to determine
1408  // whether SingleValueAgg is necessary
1409  SqlCall exprCall = (SqlCall) query;
1410  if (exprCall.getOperator() instanceof SqlValuesOperator
1411  && Util.isSingleValue(exprCall)) {
1412  return plan;
1413  }
1414  }
1415 
1416  // If not, project SingleValueAgg
1417  return RelOptUtil.createSingleValueAggRel(cluster, plan);
1418  }
+ Here is the caller graph for this function:

◆ convertUnnest()

void org.apache.calcite.sql2rel.SqlToRelConverter.convertUnnest ( Blackboard  bb,
SqlCall  call,
List< String >  fieldNames 
)
inlineprivate

Definition at line 2105 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.replaceSubQueries(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root, and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setRoot().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom().

2105  {
2106  final List<SqlNode> nodes = call.getOperandList();
2107  final SqlUnnestOperator operator = (SqlUnnestOperator) call.getOperator();
2108  for (SqlNode node : nodes) {
2109  replaceSubQueries(bb, node, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
2110  }
2111  final List<RexNode> exprs = new ArrayList<>();
2112  for (Ord<SqlNode> node : Ord.zip(nodes)) {
2113  exprs.add(relBuilder.alias(
2114  bb.convertExpression(node.e), validator.deriveAlias(node.e, node.i)));
2115  }
2116  RelNode child = (null != bb.root) ? bb.root : LogicalValues.createOneRow(cluster);
2117  RelNode uncollect;
2118  if (validator.config().sqlConformance().allowAliasUnnestItems()) {
2119  uncollect = relBuilder.push(child)
2120  .project(exprs)
2121  .uncollect(fieldNames, operator.withOrdinality)
2122  .build();
2123  } else {
2124  // REVIEW danny 2020-04-26: should we unify the normal field aliases and the
2125  // item
2126  // aliases ?
2127  uncollect = relBuilder.push(child)
2128  .project(exprs)
2129  .uncollect(Collections.emptyList(), operator.withOrdinality)
2130  .rename(fieldNames)
2131  .build();
2132  }
2133  bb.setRoot(uncollect, true);
2134  }
void replaceSubQueries(final Blackboard bb, final SqlNode expr, RelOptUtil.Logic logic)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertUpdate()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.convertUpdate ( SqlUpdate  call)
inlineprivate

Definition at line 3639 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.catalogReader, org.apache.calcite.sql2rel.SqlToRelConverter.convertSelect(), org.apache.calcite.sql2rel.SqlToRelConverter.createBlackboard(), field(), org.apache.calcite.sql2rel.SqlToRelConverter.getTargetTable(), org.apache.calcite.sql2rel.SqlToRelConverter.replaceSubQueries(), and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setRoot().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryRecursive().

3639  {
3640  final SqlValidatorScope scope = validator.getWhereScope(call.getSourceSelect());
3641  Blackboard bb = createBlackboard(scope, null, false);
3642 
3643  replaceSubQueries(bb, call, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
3644 
3645  RelOptTable targetTable = getTargetTable(call);
3646 
3647  // convert update column list from SqlIdentifier to String
3648  final List<String> targetColumnNameList = new ArrayList<>();
3649  final RelDataType targetRowType = targetTable.getRowType();
3650  for (SqlNode node : call.getTargetColumnList()) {
3651  SqlIdentifier id = (SqlIdentifier) node;
3652  RelDataTypeField field = SqlValidatorUtil.getTargetField(
3653  targetRowType, typeFactory, id, catalogReader, targetTable);
3654  assert field != null : "column " + id.toString() + " not found";
3655  targetColumnNameList.add(field.getName());
3656  }
3657 
3658  RelNode sourceRel = convertSelect(call.getSourceSelect(), false);
3659 
3660  bb.setRoot(sourceRel, false);
3661  Builder<RexNode> rexNodeSourceExpressionListBuilder = ImmutableList.builder();
3662  for (SqlNode n : call.getSourceExpressionList()) {
3663  RexNode rn = bb.convertExpression(n);
3664  rexNodeSourceExpressionListBuilder.add(rn);
3665  }
3666 
3667  return LogicalTableModify.create(targetTable,
3668  catalogReader,
3669  sourceRel,
3670  LogicalTableModify.Operation.UPDATE,
3671  targetColumnNameList,
3672  rexNodeSourceExpressionListBuilder.build(),
3673  false);
3674  }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
void replaceSubQueries(final Blackboard bb, final SqlNode expr, RelOptUtil.Logic logic)
Blackboard createBlackboard(SqlValidatorScope scope, Map< String, RexNode > nameToNodeMap, boolean top)
RelNode convertSelect(SqlSelect select, boolean top)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertUsing()

RexNode org.apache.calcite.sql2rel.SqlToRelConverter.convertUsing ( SqlValidatorNamespace  leftNamespace,
SqlValidatorNamespace  rightNamespace,
List< String >  nameList 
)
inlineprivate

Returns an expression for matching columns of a USING clause or inferred from NATURAL JOIN. "a JOIN b USING (x, y)" becomes "a.x = b.x AND a.y = b.y". Returns null if the column list is empty.

Parameters
leftNamespaceNamespace of left input to join
rightNamespaceNamespace of right input to join
nameListList of column names to join on
Returns
Expression to match columns from name list, or true if name list is empty

Definition at line 2710 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.catalogReader, and field().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom(), and org.apache.calcite.sql2rel.SqlToRelConverter.convertJoinCondition().

2712  {
2713  final SqlNameMatcher nameMatcher = catalogReader.nameMatcher();
2714  final List<RexNode> list = new ArrayList<>();
2715  for (String name : nameList) {
2716  List<RexNode> operands = new ArrayList<>();
2717  int offset = 0;
2718  for (SqlValidatorNamespace n : ImmutableList.of(leftNamespace, rightNamespace)) {
2719  final RelDataType rowType = n.getRowType();
2720  final RelDataTypeField field = nameMatcher.field(rowType, name);
2721  operands.add(rexBuilder.makeInputRef(field.getType(), offset + field.getIndex()));
2722  offset += rowType.getFieldList().size();
2723  }
2724  list.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, operands));
2725  }
2726  return RexUtil.composeConjunction(rexBuilder, list);
2727  }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertValues()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.convertValues ( SqlCall  values,
RelDataType  targetRowType 
)
inline

Converts a SELECT statement's parse tree into a relational expression.

Definition at line 4044 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.convertValuesImpl(), org.apache.calcite.sql2rel.SqlToRelConverter.createBlackboard(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root, and org.apache.calcite.sql2rel.SqlToRelConverter.validator.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryRecursive().

4044  {
4045  final SqlValidatorScope scope = validator.getOverScope(values);
4046  assert scope != null;
4047  final Blackboard bb = createBlackboard(scope, null, false);
4048  convertValuesImpl(bb, values, targetRowType);
4049  return bb.root;
4050  }
void convertValuesImpl(Blackboard bb, SqlCall values, RelDataType targetRowType)
Blackboard createBlackboard(SqlValidatorScope scope, Map< String, RexNode > nameToNodeMap, boolean top)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertValuesImpl()

void org.apache.calcite.sql2rel.SqlToRelConverter.convertValuesImpl ( Blackboard  bb,
SqlCall  values,
RelDataType  targetRowType 
)
inlineprivate

Converts a values clause (as in "INSERT INTO T(x,y) VALUES (1,2)") into a relational expression.

Parameters
bbBlackboard
valuesCall to SQL VALUES operator
targetRowTypeTarget row type

Definition at line 4060 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.cluster, org.apache.calcite.sql2rel.SqlToRelConverter.convertRowValues(), org.apache.calcite.sql2rel.SqlToRelConverter.createBlackboard(), org.apache.calcite.sql2rel.SqlToRelConverter.relBuilder, org.apache.calcite.sql2rel.SqlToRelConverter.replaceSubQueries(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root, org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.scope, org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setRoot(), and org.apache.calcite.sql2rel.SqlToRelConverter.validator.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom(), and org.apache.calcite.sql2rel.SqlToRelConverter.convertValues().

4061  {
4062  // Attempt direct conversion to LogicalValues; if that fails, deal with
4063  // fancy stuff like sub-queries below.
4064  RelNode valuesRel =
4065  convertRowValues(bb, values, values.getOperandList(), true, targetRowType);
4066  if (valuesRel != null) {
4067  bb.setRoot(valuesRel, true);
4068  return;
4069  }
4070 
4071  final List<RelNode> unionRels = new ArrayList<>();
4072  for (SqlNode rowConstructor1 : values.getOperandList()) {
4073  SqlCall rowConstructor = (SqlCall) rowConstructor1;
4074  Blackboard tmpBb = createBlackboard(bb.scope, null, false);
4075  replaceSubQueries(tmpBb, rowConstructor, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
4076  final List<Pair<RexNode, String>> exps = new ArrayList<>();
4077  for (Ord<SqlNode> operand : Ord.zip(rowConstructor.getOperandList())) {
4078  exps.add(Pair.of(tmpBb.convertExpression(operand.e),
4079  validator.deriveAlias(operand.e, operand.i)));
4080  }
4081  RelNode in =
4082  (null == tmpBb.root) ? LogicalValues.createOneRow(cluster) : tmpBb.root;
4083  unionRels.add(
4084  relBuilder.push(in).project(Pair.left(exps), Pair.right(exps)).build());
4085  }
4086 
4087  if (unionRels.size() == 0) {
4088  throw new AssertionError("empty values clause");
4089  } else if (unionRels.size() == 1) {
4090  bb.setRoot(unionRels.get(0), true);
4091  } else {
4092  bb.setRoot(LogicalUnion.create(unionRels, true), true);
4093  }
4094  }
RelNode convertRowValues(Blackboard bb, SqlNode rowList, Collection< SqlNode > rows, boolean allowLiteralsOnly, RelDataType targetRowType)
void replaceSubQueries(final Blackboard bb, final SqlNode expr, RelOptUtil.Logic logic)
Blackboard createBlackboard(SqlValidatorScope scope, Map< String, RexNode > nameToNodeMap, boolean top)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertWhere()

void org.apache.calcite.sql2rel.SqlToRelConverter.convertWhere ( final Blackboard  bb,
final SqlNode  where 
)
inlineprivate

Converts a WHERE clause.

Parameters
bbBlackboard
whereWHERE clause, may be null

Definition at line 967 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.getCorrelationUse(), org.apache.calcite.sql2rel.SqlToRelConverter.pushDownNotForIn(), org.apache.calcite.sql2rel.SqlToRelConverter.replaceSubQueries(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root, org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.scope, and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setRoot().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertSelectImpl().

967  {
968  if (where == null) {
969  return;
970  }
971  SqlNode newWhere = pushDownNotForIn(bb.scope, where);
972  replaceSubQueries(bb, newWhere, RelOptUtil.Logic.UNKNOWN_AS_FALSE);
973  final RexNode convertedWhere = bb.convertExpression(newWhere);
974  final RexNode convertedWhere2 =
975  RexUtil.removeNullabilityCast(typeFactory, convertedWhere);
976 
977  // only allocate filter if the condition is not TRUE
978  if (convertedWhere2.isAlwaysTrue()) {
979  return;
980  }
981 
982  final RelFactories.FilterFactory filterFactory = RelFactories.DEFAULT_FILTER_FACTORY;
983  final RelNode filter =
984  filterFactory.createFilter(bb.root, convertedWhere2, ImmutableSet.of());
985  final RelNode r;
986  final CorrelationUse p = getCorrelationUse(bb, filter);
987  if (p != null) {
988  assert p.r instanceof Filter;
989  Filter f = (Filter) p.r;
990  r = LogicalFilter.create(f.getInput(), f.getCondition(), ImmutableSet.of(p.id));
991  } else {
992  r = filter;
993  }
994 
995  bb.setRoot(r, false);
996  }
static SqlNode pushDownNotForIn(SqlValidatorScope scope, SqlNode sqlNode)
void replaceSubQueries(final Blackboard bb, final SqlNode expr, RelOptUtil.Logic logic)
CorrelationUse getCorrelationUse(Blackboard bb, final RelNode r0)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ convertWith()

RelRoot org.apache.calcite.sql2rel.SqlToRelConverter.convertWith ( SqlWith  with,
boolean  top 
)
inline

Converts a WITH sub-query into a relational expression.

Definition at line 4037 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.convertQuery().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryRecursive().

4037  {
4038  return convertQuery(with.body, false, top);
4039  }
RelRoot convertQuery(SqlNode query, final boolean needsValidation, final boolean top)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ createAggImpl()

final void org.apache.calcite.sql2rel.SqlToRelConverter.createAggImpl ( Blackboard  bb,
final AggConverter  aggConverter,
SqlNodeList  selectList,
SqlNodeList  groupList,
SqlNode  having,
List< SqlNode >  orderExprList 
)
inlineprotected

Definition at line 2770 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.agg, org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.columnMonotonicities, org.apache.calcite.sql2rel.SqlToRelConverter.createAggregate(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.mapRootRelToFieldProjection, org.apache.calcite.sql2rel.SqlToRelConverter.pushDownNotForIn(), org.apache.calcite.sql2rel.SqlToRelConverter.replaceSubQueries(), org.apache.calcite.sql2rel.SqlToRelConverter.rewriteAggregateWithGroupId(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root, org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.scope, and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setRoot().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertAgg().

2775  {
2776  // Find aggregate functions in SELECT and HAVING clause
2777  final AggregateFinder aggregateFinder = new AggregateFinder();
2778  selectList.accept(aggregateFinder);
2779  if (having != null) {
2780  having.accept(aggregateFinder);
2781  }
2782 
2783  // first replace the sub-queries inside the aggregates
2784  // because they will provide input rows to the aggregates.
2785  replaceSubQueries(bb, aggregateFinder.list, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
2786 
2787  // also replace sub-queries inside filters in the aggregates
2789  bb, aggregateFinder.filterList, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
2790 
2791  // also replace sub-queries inside ordering spec in the aggregates
2792  replaceSubQueries(bb, aggregateFinder.orderList, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
2793 
2794  // If group-by clause is missing, pretend that it has zero elements.
2795  if (groupList == null) {
2796  groupList = SqlNodeList.EMPTY;
2797  }
2798 
2799  replaceSubQueries(bb, groupList, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
2800 
2801  // register the group exprs
2802 
2803  // build a map to remember the projections from the top scope to the
2804  // output of the current root.
2805  //
2806  // Calcite allows expressions, not just column references in
2807  // group by list. This is not SQL 2003 compliant, but hey.
2808 
2809  final AggregatingSelectScope scope = aggConverter.aggregatingSelectScope;
2810  final AggregatingSelectScope.Resolved r = scope.resolved.get();
2811  for (SqlNode groupExpr : r.groupExprList) {
2812  aggConverter.addGroupExpr(groupExpr);
2813  }
2814 
2815  final RexNode havingExpr;
2816  final List<Pair<RexNode, String>> projects = new ArrayList<>();
2817 
2818  try {
2819  Preconditions.checkArgument(bb.agg == null, "already in agg mode");
2820  bb.agg = aggConverter;
2821 
2822  // convert the select and having expressions, so that the
2823  // agg converter knows which aggregations are required
2824 
2825  selectList.accept(aggConverter);
2826  // Assert we don't have dangling items left in the stack
2827  assert !aggConverter.inOver;
2828  for (SqlNode expr : orderExprList) {
2829  expr.accept(aggConverter);
2830  assert !aggConverter.inOver;
2831  }
2832  if (having != null) {
2833  having.accept(aggConverter);
2834  assert !aggConverter.inOver;
2835  }
2836 
2837  // compute inputs to the aggregator
2838  List<Pair<RexNode, String>> preExprs = aggConverter.getPreExprs();
2839 
2840  if (preExprs.size() == 0) {
2841  // Special case for COUNT(*), where we can end up with no inputs
2842  // at all. The rest of the system doesn't like 0-tuples, so we
2843  // select a dummy constant here.
2844  final RexNode zero = rexBuilder.makeExactLiteral(BigDecimal.ZERO);
2845  preExprs = ImmutableList.of(Pair.of(zero, (String) null));
2846  }
2847 
2848  final RelNode inputRel = bb.root;
2849 
2850  // Project the expressions required by agg and having.
2851  bb.setRoot(relBuilder.push(inputRel)
2852  .projectNamed(Pair.left(preExprs), Pair.right(preExprs), false)
2853  .build(),
2854  false);
2855  bb.mapRootRelToFieldProjection.put(bb.root, r.groupExprProjection);
2856 
2857  // REVIEW jvs 31-Oct-2007: doesn't the declaration of
2858  // monotonicity here assume sort-based aggregation at
2859  // the physical level?
2860 
2861  // Tell bb which of group columns are sorted.
2862  bb.columnMonotonicities.clear();
2863  for (SqlNode groupItem : groupList) {
2864  bb.columnMonotonicities.add(bb.scope.getMonotonicity(groupItem));
2865  }
2866 
2867  final RelNode relNode = aggConverter.containsGroupId()
2868  ? rewriteAggregateWithGroupId(bb, r, aggConverter)
2869  : createAggregate(bb, r.groupSet, r.groupSets, aggConverter.getAggCalls());
2870 
2871  bb.setRoot(relNode, false);
2872  bb.mapRootRelToFieldProjection.put(bb.root, r.groupExprProjection);
2873 
2874  // Replace sub-queries in having here and modify having to use
2875  // the replaced expressions
2876  if (having != null) {
2877  SqlNode newHaving = pushDownNotForIn(bb.scope, having);
2878  replaceSubQueries(bb, newHaving, RelOptUtil.Logic.UNKNOWN_AS_FALSE);
2879  havingExpr = bb.convertExpression(newHaving);
2880  } else {
2881  havingExpr = relBuilder.literal(true);
2882  }
2883 
2884  // Now convert the other sub-queries in the select list.
2885  // This needs to be done separately from the sub-query inside
2886  // any aggregate in the select list, and after the aggregate rel
2887  // is allocated.
2888  replaceSubQueries(bb, selectList, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
2889 
2890  // Now sub-queries in the entire select list have been converted.
2891  // Convert the select expressions to get the final list to be
2892  // projected.
2893  int k = 0;
2894 
2895  // For select expressions, use the field names previously assigned
2896  // by the validator. If we derive afresh, we might generate names
2897  // like "EXPR$2" that don't match the names generated by the
2898  // validator. This is especially the case when there are system
2899  // fields; system fields appear in the relnode's rowtype but do not
2900  // (yet) appear in the validator type.
2901  final SelectScope selectScope = SqlValidatorUtil.getEnclosingSelectScope(bb.scope);
2902  assert selectScope != null;
2903  final SqlValidatorNamespace selectNamespace =
2904  validator.getNamespace(selectScope.getNode());
2905  final List<String> names = selectNamespace.getRowType().getFieldNames();
2906  int sysFieldCount = selectList.size() - names.size();
2907  for (SqlNode expr : selectList) {
2908  projects.add(Pair.of(bb.convertExpression(expr),
2909  k < sysFieldCount ? validator.deriveAlias(expr, k++)
2910  : names.get(k++ - sysFieldCount)));
2911  }
2912 
2913  for (SqlNode expr : orderExprList) {
2914  projects.add(
2915  Pair.of(bb.convertExpression(expr), validator.deriveAlias(expr, k++)));
2916  }
2917  } finally {
2918  bb.agg = null;
2919  }
2920 
2921  // implement HAVING (we have already checked that it is non-trivial)
2922  relBuilder.push(bb.root);
2923  if (havingExpr != null) {
2924  relBuilder.filter(havingExpr);
2925  }
2926 
2927  // implement the SELECT list
2928  relBuilder.project(Pair.left(projects), Pair.right(projects))
2929  .rename(Pair.right(projects));
2930  bb.setRoot(relBuilder.build(), false);
2931 
2932  // Tell bb which of group columns are sorted.
2933  bb.columnMonotonicities.clear();
2934  for (SqlNode selectItem : selectList) {
2935  bb.columnMonotonicities.add(bb.scope.getMonotonicity(selectItem));
2936  }
2937  }
static SqlNode pushDownNotForIn(SqlValidatorScope scope, SqlNode sqlNode)
void replaceSubQueries(final Blackboard bb, final SqlNode expr, RelOptUtil.Logic logic)
RelNode createAggregate(Blackboard bb, ImmutableBitSet groupSet, ImmutableList< ImmutableBitSet > groupSets, List< AggregateCall > aggCalls)
RelNode rewriteAggregateWithGroupId(Blackboard bb, AggregatingSelectScope.Resolved r, AggConverter converter)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ createAggregate()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.createAggregate ( Blackboard  bb,
ImmutableBitSet  groupSet,
ImmutableList< ImmutableBitSet >  groupSets,
List< AggregateCall >  aggCalls 
)
inlineprotected

Creates an Aggregate.

In case the aggregate rel changes the order in which it projects fields, the groupExprProjection parameter is provided, and the implementation of this method may modify it.

The sortedCount parameter is the number of expressions known to be monotonic. These expressions must be on the leading edge of the grouping keys. The default implementation of this method ignores this parameter.

Parameters
bbBlackboard
groupSetBit set of ordinals of grouping columns
groupSetsGrouping sets
aggCallsArray of calls to aggregate functions
Returns
LogicalAggregate

Definition at line 3059 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.createAggImpl(), org.apache.calcite.sql2rel.SqlToRelConverter.distinctify(), and org.apache.calcite.sql2rel.SqlToRelConverter.rewriteAggregateWithGroupId().

3062  {
3063  return LogicalAggregate.create(
3064  bb.root, ImmutableList.of(), groupSet, groupSets, aggCalls);
3065  }
+ Here is the caller graph for this function:

◆ createBlackboard()

Blackboard org.apache.calcite.sql2rel.SqlToRelConverter.createBlackboard ( SqlValidatorScope  scope,
Map< String, RexNode >  nameToNodeMap,
boolean  top 
)
inlineprotected

◆ createInsertBlackboard()

Blackboard org.apache.calcite.sql2rel.SqlToRelConverter.createInsertBlackboard ( RelOptTable  targetTable,
RexNode  sourceRef,
List< String >  targetColumnNames 
)
inlineprivate

Creates a blackboard for translating the expressions of generated columns in an INSERT statement.

Definition at line 3509 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.createBlackboard().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.collectInsertTargets(), org.apache.calcite.sql2rel.SqlToRelConverter.convertColumnList(), and org.apache.calcite.sql2rel.SqlToRelConverter.toRel().

3510  {
3511  final Map<String, RexNode> nameToNodeMap = new HashMap<>();
3512  int j = 0;
3513 
3514  // Assign expressions for non-generated columns.
3515  final List<ColumnStrategy> strategies = targetTable.getColumnStrategies();
3516  final List<String> targetFields = targetTable.getRowType().getFieldNames();
3517  for (String targetColumnName : targetColumnNames) {
3518  final int i = targetFields.indexOf(targetColumnName);
3519  switch (strategies.get(i)) {
3520  case STORED:
3521  case VIRTUAL:
3522  break;
3523  default:
3524  nameToNodeMap.put(targetColumnName, rexBuilder.makeFieldAccess(sourceRef, j++));
3525  }
3526  }
3527  return createBlackboard(null, nameToNodeMap, false);
3528  }
Blackboard createBlackboard(SqlValidatorScope scope, Map< String, RexNode > nameToNodeMap, boolean top)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ createJoin()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.createJoin ( Blackboard  bb,
RelNode  leftRel,
RelNode  rightRel,
RexNode  joinCond,
JoinRelType  joinType 
)
inlineprotected

Definition at line 2444 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.config, org.apache.calcite.sql2rel.SqlToRelConverter.getCorrelationUse(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.getTopNode(), org.apache.calcite.sql2rel.SqlToRelConverter.RexAccessShuttle.RexAccessShuttle(), org.apache.calcite.sql2rel.SqlToRelConverter.RexAccessShuttle.rexCorrel, and org.apache.calcite.sql2rel.SqlToRelConverter.RexAccessShuttle.varCols.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertFrom(), and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.register().

2448  {
2449  assert joinCond != null;
2450 
2451  final CorrelationUse p = getCorrelationUse(bb, rightRel);
2452  if (p != null) {
2453  RelNode innerRel = p.r;
2454  ImmutableBitSet requiredCols = p.requiredColumns;
2455 
2456  if (!joinCond.isAlwaysTrue()) {
2457  final RelFactories.FilterFactory factory = RelFactories.DEFAULT_FILTER_FACTORY;
2458  final RexCorrelVariable rexCorrel =
2459  (RexCorrelVariable) rexBuilder.makeCorrel(leftRel.getRowType(), p.id);
2460  final RexAccessShuttle shuttle = new RexAccessShuttle(rexBuilder, rexCorrel);
2461 
2462  // Replace outer RexInputRef with RexFieldAccess,
2463  // and push lateral join predicate into inner child
2464  final RexNode newCond = joinCond.accept(shuttle);
2465  innerRel = factory.createFilter(p.r, newCond, ImmutableSet.of());
2466  requiredCols =
2467  ImmutableBitSet.fromBitSet(shuttle.varCols).union(p.requiredColumns);
2468  }
2469 
2470  LogicalCorrelate corr =
2471  LogicalCorrelate.create(leftRel, innerRel, p.id, requiredCols, joinType);
2472  return corr;
2473  }
2474 
2475  final Join originalJoin = (Join) RelFactories.DEFAULT_JOIN_FACTORY.createJoin(leftRel,
2476  rightRel,
2477  ImmutableList.of(),
2478  joinCond,
2479  ImmutableSet.of(),
2480  joinType,
2481  false);
2482 
2483  RelNode node;
2484  boolean applyPushdown =
2485  config.getPushdownJoinCondition().test(bb.getTopNode(), originalJoin);
2486  if (applyPushdown) {
2487  node = RelOptUtil.pushDownJoinConditions(originalJoin, relBuilder);
2488  } else {
2489  node = originalJoin;
2490  }
2491 
2492  // If join conditions are pushed down, update the leaves.
2493  if (node instanceof Project) {
2494  final Join newJoin = (Join) node.getInputs().get(0);
2495  if (leaves.containsKey(leftRel)) {
2496  leaves.put(newJoin.getLeft(), leaves.get(leftRel));
2497  }
2498  if (leaves.containsKey(rightRel)) {
2499  leaves.put(newJoin.getRight(), leaves.get(rightRel));
2500  }
2501  }
2502  return node;
2503  }
CorrelationUse getCorrelationUse(Blackboard bb, final RelNode r0)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ createModify()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.createModify ( RelOptTable  targetTable,
RelNode  source 
)
inlineprivate

Creates a relational expression to modify a table or modifiable view.

Definition at line 3298 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.catalogReader, and org.apache.calcite.sql2rel.SqlToRelConverter.createSource().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertInsert().

3298  {
3299  final ModifiableTable modifiableTable = targetTable.unwrap(ModifiableTable.class);
3300  if (modifiableTable != null && modifiableTable == targetTable.unwrap(Table.class)) {
3301  return modifiableTable.toModificationRel(cluster,
3302  targetTable,
3303  catalogReader,
3304  source,
3305  LogicalTableModify.Operation.INSERT,
3306  null,
3307  null,
3308  false);
3309  }
3310  final ModifiableView modifiableView = targetTable.unwrap(ModifiableView.class);
3311  if (modifiableView != null) {
3312  final Table delegateTable = modifiableView.getTable();
3313  final RelDataType delegateRowType = delegateTable.getRowType(typeFactory);
3314  final RelOptTable delegateRelOptTable = RelOptTableImpl.create(
3315  null, delegateRowType, delegateTable, modifiableView.getTablePath());
3316  final RelNode newSource =
3317  createSource(targetTable, source, modifiableView, delegateRowType);
3318  return createModify(delegateRelOptTable, newSource);
3319  }
3320  return LogicalTableModify.create(targetTable,
3321  catalogReader,
3322  source,
3323  LogicalTableModify.Operation.INSERT,
3324  null,
3325  null,
3326  false);
3327  }
RelNode createSource(RelOptTable targetTable, RelNode source, ModifiableView modifiableView, RelDataType delegateRowType)
RelNode createModify(RelOptTable targetTable, RelNode source)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ createSource()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.createSource ( RelOptTable  targetTable,
RelNode  source,
ModifiableView  modifiableView,
RelDataType  delegateRowType 
)
inlineprivate

Wraps a relational expression in the projects and filters implied by a ModifiableView.

The input relational expression is suitable for inserting into the view, and the returned relational expression is suitable for inserting into its delegate table.

In principle, the delegate table of a view might be another modifiable view, and if so, the process can be repeated.

Definition at line 3342 of file SqlToRelConverter.java.

References field().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.createModify().

3345  {
3346  final ImmutableIntList mapping = modifiableView.getColumnMapping();
3347  assert mapping.size() == targetTable.getRowType().getFieldCount();
3348 
3349  // For columns represented in the mapping, the expression is just a field
3350  // reference.
3351  final Map<Integer, RexNode> projectMap = new HashMap<>();
3352  final List<RexNode> filters = new ArrayList<>();
3353  for (int i = 0; i < mapping.size(); i++) {
3354  int target = mapping.get(i);
3355  if (target >= 0) {
3356  projectMap.put(target, RexInputRef.of(i, source.getRowType()));
3357  }
3358  }
3359 
3360  // For columns that are not in the mapping, and have a constraint of the
3361  // form "column = value", the expression is the literal "value".
3362  //
3363  // If a column has multiple constraints, the extra ones will become a
3364  // filter.
3365  final RexNode constraint = modifiableView.getConstraint(rexBuilder, delegateRowType);
3366  RelOptUtil.inferViewPredicates(projectMap, filters, constraint);
3367  final List<Pair<RexNode, String>> projects = new ArrayList<>();
3368  for (RelDataTypeField field : delegateRowType.getFieldList()) {
3369  RexNode node = projectMap.get(field.getIndex());
3370  if (node == null) {
3371  node = rexBuilder.makeNullLiteral(field.getType());
3372  }
3373  projects.add(Pair.of(
3374  rexBuilder.ensureType(field.getType(), node, false), field.getName()));
3375  }
3376 
3377  return relBuilder.push(source)
3378  .projectNamed(Pair.left(projects), Pair.right(projects), false)
3379  .filter(filters)
3380  .build();
3381  }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ createToRelContext()

RelOptTable.ToRelContext org.apache.calcite.sql2rel.SqlToRelConverter.createToRelContext ( List< RelHint >  hints)
inlineprivate

Definition at line 3383 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.viewExpander.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.flattenTypes(), and org.apache.calcite.sql2rel.SqlToRelConverter.toRel().

3383  {
3384  return ViewExpanders.toRelContext(viewExpander, cluster, hints);
3385  }
+ Here is the caller graph for this function:

◆ decorrelate()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.decorrelate ( SqlNode  query,
RelNode  rootRel 
)
inline

If sub-query is correlated and decorrelation is enabled, performs decorrelation.

Parameters
queryQuery
rootRelRoot relational expression
Returns
New root relational expression after decorrelation

Definition at line 479 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.checkConvertedType(), org.apache.calcite.sql2rel.SqlToRelConverter.decorrelateQuery(), org.apache.calcite.sql2rel.SqlToRelConverter.enableDecorrelation(), and run_benchmark_import.result.

479  {
480  if (!enableDecorrelation()) {
481  return rootRel;
482  }
483  final RelNode result = decorrelateQuery(rootRel);
484  if (result != rootRel) {
485  checkConvertedType(query, result);
486  }
487  return result;
488  }
void checkConvertedType(SqlNode query, RelNode result)
+ Here is the call graph for this function:

◆ decorrelateQuery()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.decorrelateQuery ( RelNode  rootRel)
inlineprotected

Definition at line 3206 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.decorrelate().

3206  {
3207  return RelDecorrelator.decorrelateQuery(rootRel, relBuilder);
3208  }
+ Here is the caller graph for this function:

◆ deriveAlias()

String org.apache.calcite.sql2rel.SqlToRelConverter.deriveAlias ( final SqlNode  node,
Collection< String >  aliases,
final int  ordinal 
)
inlineprivate

Definition at line 4018 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.validator.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertSelectList().

4019  {
4020  String alias = validator.deriveAlias(node, ordinal);
4021  if ((alias == null) || aliases.contains(alias)) {
4022  String aliasBase = (alias == null) ? "EXPR$" : alias;
4023  for (int j = 0;; j++) {
4024  alias = aliasBase + j;
4025  if (!aliases.contains(alias)) {
4026  break;
4027  }
4028  }
4029  }
4030  aliases.add(alias);
4031  return alias;
4032  }
+ Here is the caller graph for this function:

◆ desc()

static boolean org.apache.calcite.sql2rel.SqlToRelConverter.desc ( RelFieldCollation.Direction  direction)
inlinestaticprivate

Definition at line 3189 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertMatchRecognize(), org.apache.calcite.sql2rel.SqlToRelConverter.convertOrderItem(), and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.lookupExp().

3189  {
3190  switch (direction) {
3191  case DESCENDING:
3192  case STRICTLY_DESCENDING:
3193  return true;
3194  default:
3195  return false;
3196  }
3197  }
+ Here is the caller graph for this function:

◆ distinctify()

void org.apache.calcite.sql2rel.SqlToRelConverter.distinctify ( Blackboard  bb,
boolean  checkForDupExprs 
)
inlineprivate

Having translated 'SELECT ... FROM ... [GROUP BY ...] [HAVING ...]', adds a relational expression to make the results unique.

If the SELECT clause contains duplicate expressions, adds org.apache.calcite.rel.logical.LogicalProjects so that we are grouping on the minimal set of keys. The performance gain isn't huge, but it is difficult to detect these duplicate expressions later.

Parameters
bbBlackboard
checkForDupExprsCheck for duplicate expressions

Definition at line 709 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.createAggregate(), field(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root, and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setRoot().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertSelectImpl().

709  {
710  // Look for duplicate expressions in the project.
711  // Say we have 'select x, y, x, z'.
712  // Then dups will be {[2, 0]}
713  // and oldToNew will be {[0, 0], [1, 1], [2, 0], [3, 2]}
714  RelNode rel = bb.root;
715  if (checkForDupExprs && (rel instanceof LogicalProject)) {
716  LogicalProject project = (LogicalProject) rel;
717  final List<RexNode> projectExprs = project.getProjects();
718  final List<Integer> origins = new ArrayList<>();
719  int dupCount = 0;
720  for (int i = 0; i < projectExprs.size(); i++) {
721  int x = projectExprs.indexOf(projectExprs.get(i));
722  if (x >= 0 && x < i) {
723  origins.add(x);
724  ++dupCount;
725  } else {
726  origins.add(i);
727  }
728  }
729  if (dupCount == 0) {
730  distinctify(bb, false);
731  return;
732  }
733 
734  final Map<Integer, Integer> squished = new HashMap<>();
735  final List<RelDataTypeField> fields = rel.getRowType().getFieldList();
736  final List<Pair<RexNode, String>> newProjects = new ArrayList<>();
737  for (int i = 0; i < fields.size(); i++) {
738  if (origins.get(i) == i) {
739  squished.put(i, newProjects.size());
740  newProjects.add(RexInputRef.of2(i, fields));
741  }
742  }
743  rel = LogicalProject.create(
744  rel, ImmutableList.of(), Pair.left(newProjects), Pair.right(newProjects));
745  bb.root = rel;
746  distinctify(bb, false);
747  rel = bb.root;
748 
749  // Create the expressions to reverse the mapping.
750  // Project($0, $1, $0, $2).
751  final List<Pair<RexNode, String>> undoProjects = new ArrayList<>();
752  for (int i = 0; i < fields.size(); i++) {
753  final int origin = origins.get(i);
754  RelDataTypeField field = fields.get(i);
755  undoProjects.add(
756  Pair.of((RexNode) new RexInputRef(squished.get(origin), field.getType()),
757  field.getName()));
758  }
759 
760  rel = LogicalProject.create(
761  rel, ImmutableList.of(), Pair.left(undoProjects), Pair.right(undoProjects));
762  bb.setRoot(rel, false);
763 
764  return;
765  }
766 
767  // Usual case: all of the expressions in the SELECT clause are
768  // different.
769  final ImmutableBitSet groupSet =
770  ImmutableBitSet.range(rel.getRowType().getFieldCount());
771  rel = createAggregate(bb, groupSet, ImmutableList.of(groupSet), ImmutableList.of());
772 
773  bb.setRoot(rel, false);
774  }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
void distinctify(Blackboard bb, boolean checkForDupExprs)
RelNode createAggregate(Blackboard bb, ImmutableBitSet groupSet, ImmutableList< ImmutableBitSet > groupSets, List< AggregateCall > aggCalls)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ enableDecorrelation()

boolean org.apache.calcite.sql2rel.SqlToRelConverter.enableDecorrelation ( )
inlineprotected

Definition at line 3200 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.config.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.decorrelate().

3200  {
3201  // disable sub-query decorrelation when needed.
3202  // e.g. if outer joins are not supported.
3203  return config.isDecorrelationEnabled();
3204  }
+ Here is the caller graph for this function:

◆ ensureSqlType()

RexNode org.apache.calcite.sql2rel.SqlToRelConverter.ensureSqlType ( RelDataType  type,
RexNode  node 
)
inlineprivate

Ensures that an expression has a given SqlTypeName, applying a cast if necessary. If the expression already has the right type family, returns the expression unchanged.

Definition at line 1482 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertInToOr().

1482  {
1483  if (type.getSqlTypeName() == node.getType().getSqlTypeName()
1484  || (type.getSqlTypeName() == SqlTypeName.VARCHAR
1485  && node.getType().getSqlTypeName() == SqlTypeName.CHAR)) {
1486  return node;
1487  }
1488  return rexBuilder.ensureType(type, node, true);
1489  }
+ Here is the caller graph for this function:

◆ extraSelectItems()

void org.apache.calcite.sql2rel.SqlToRelConverter.extraSelectItems ( Blackboard  bb,
SqlSelect  select,
List< RexNode >  exprList,
List< String >  nameList,
Collection< String >  aliasList,
List< SqlMonotonicity >  columnMonotonicityList 
)
inlineprotected

Adds extra select items. The default implementation adds nothing; derived classes may add columns to exprList, nameList, aliasList and columnMonotonicityList.

Parameters
bbBlackboard
selectSelect statement being translated
exprListList of expressions in select clause
nameListList of names, one per column
aliasListCollection of aliases that have been used already
columnMonotonicityListList of monotonicity, one per column

Definition at line 4011 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertSelectList().

4016  {}
+ Here is the caller graph for this function:

◆ findSubQueries()

void org.apache.calcite.sql2rel.SqlToRelConverter.findSubQueries ( Blackboard  bb,
SqlNode  node,
RelOptUtil.Logic  logic,
boolean  registerOnlyScalarSubQueries 
)
inlineprivate

Builds a list of all IN or EXISTS operators inside SQL parse tree. Does not traverse inside queries.

Parameters
bbblackboard
nodethe SQL parse tree
logicWhether the answer needs to be in full 3-valued logic (TRUE, FALSE, UNKNOWN) will be required, or whether we can accept an approximation (say representing UNKNOWN as FALSE)
registerOnlyScalarSubQueriesif set to true and the parse tree corresponds to a variation of a select node, only register it if it's a scalar sub-query

Definition at line 1697 of file SqlToRelConverter.java.

References run_benchmark_import.type.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.replaceSubQueries().

1700  {
1701  final SqlKind kind = node.getKind();
1702  switch (kind) {
1703  case EXISTS:
1704  case SELECT:
1705  case MULTISET_QUERY_CONSTRUCTOR:
1706  case MULTISET_VALUE_CONSTRUCTOR:
1707  case ARRAY_QUERY_CONSTRUCTOR:
1708  case CURSOR:
1709  case SCALAR_QUERY:
1710  if (!registerOnlyScalarSubQueries || (kind == SqlKind.SCALAR_QUERY)) {
1711  bb.registerSubQuery(node, RelOptUtil.Logic.TRUE_FALSE);
1712  }
1713  return;
1714  case IN:
1715  break;
1716  case NOT_IN:
1717  case NOT:
1718  logic = logic.negate();
1719  break;
1720  }
1721  if (node instanceof SqlCall) {
1722  switch (kind) {
1723  // Do no change logic for AND, IN and NOT IN expressions;
1724  // but do change logic for OR, NOT and others;
1725  // EXISTS was handled already.
1726  case AND:
1727  case IN:
1728  case NOT_IN:
1729  break;
1730  default:
1731  logic = RelOptUtil.Logic.TRUE_FALSE_UNKNOWN;
1732  break;
1733  }
1734  for (SqlNode operand : ((SqlCall) node).getOperandList()) {
1735  if (operand != null) {
1736  // In the case of an IN expression, locate scalar
1737  // sub-queries so we can convert them to constants
1738  findSubQueries(bb,
1739  operand,
1740  logic,
1741  kind == SqlKind.IN || kind == SqlKind.NOT_IN || kind == SqlKind.SOME
1742  || kind == SqlKind.ALL || registerOnlyScalarSubQueries);
1743  }
1744  }
1745  } else if (node instanceof SqlNodeList) {
1746  for (SqlNode child : (SqlNodeList) node) {
1747  findSubQueries(bb,
1748  child,
1749  logic,
1750  kind == SqlKind.IN || kind == SqlKind.NOT_IN || kind == SqlKind.SOME
1751  || kind == SqlKind.ALL || registerOnlyScalarSubQueries);
1752  }
1753  }
1754 
1755  // Now that we've located any scalar sub-queries inside the IN
1756  // expression, register the IN expression itself. We need to
1757  // register the scalar sub-queries first so they can be converted
1758  // before the IN expression is converted.
1759  switch (kind) {
1760  case IN:
1761  case NOT_IN:
1762  case SOME:
1763  case ALL:
1764  switch (logic) {
1765  case TRUE_FALSE_UNKNOWN:
1766  RelDataType type = validator.getValidatedNodeTypeIfKnown(node);
1767  if (type == null) {
1768  // The node might not be validated if we still don't know type of the node.
1769  // Therefore return directly.
1770  return;
1771  } else {
1772  break;
1773  }
1774  // fall through
1775  case UNKNOWN_AS_FALSE:
1776  logic = RelOptUtil.Logic.TRUE;
1777  }
1778  bb.registerSubQuery(node, logic);
1779  break;
1780  }
1781  }
void findSubQueries(Blackboard bb, SqlNode node, RelOptUtil.Logic logic, boolean registerOnlyScalarSubQueries)
+ Here is the caller graph for this function:

◆ flattenTypes()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.flattenTypes ( RelNode  rootRel,
boolean  restructure 
)
inline

Definition at line 465 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.createToRelContext().

465  {
466  RelStructuredTypeFlattener typeFlattener = new RelStructuredTypeFlattener(
467  relBuilder, rexBuilder, createToRelContext(ImmutableList.of()), restructure);
468  return typeFlattener.rewrite(rootRel);
469  }
RelOptTable.ToRelContext createToRelContext(List< RelHint > hints)
+ Here is the call graph for this function:

◆ gatherOrderExprs()

void org.apache.calcite.sql2rel.SqlToRelConverter.gatherOrderExprs ( Blackboard  bb,
SqlSelect  select,
SqlNodeList  orderList,
List< SqlNode >  extraOrderExprs,
List< RelFieldCollation >  collationList 
)
inlineprotected

Creates a list of collations required to implement the ORDER BY clause, if there is one. Populates extraOrderExprs with any sort expressions which are not in the select clause.

Parameters
bbScope within which to resolve identifiers
selectSelect clause. Never null, because we invent a dummy SELECT if ORDER BY is applied to a set operation (UNION etc.)
orderListOrder by clause, may be null
extraOrderExprsSort expressions which are not in the select clause (output)
collationListList of collations (output)

Definition at line 3095 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.convertOrderItem(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root, and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.top.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertSelectImpl().

3099  {
3100  // TODO: add validation rules to SqlValidator also
3101  assert bb.root != null : "precondition: child != null";
3102  assert select != null;
3103  if (orderList == null) {
3104  return;
3105  }
3106 
3107  if (!bb.top) {
3108  SqlNode offset = select.getOffset();
3109  if ((offset == null
3110  || (offset instanceof SqlLiteral
3111  && ((SqlLiteral) offset)
3112  .bigDecimalValue()
3113  .equals(BigDecimal.ZERO)))
3114  && select.getFetch() == null) {
3115  return;
3116  }
3117  }
3118 
3119  for (SqlNode orderItem : orderList) {
3120  collationList.add(convertOrderItem(select,
3121  orderItem,
3122  extraOrderExprs,
3123  RelFieldCollation.Direction.ASCENDING,
3124  RelFieldCollation.NullDirection.UNSPECIFIED));
3125  }
3126  }
RelFieldCollation convertOrderItem(SqlSelect select, SqlNode orderItem, List< SqlNode > extraExprs, RelFieldCollation.Direction direction, RelFieldCollation.NullDirection nullDirection)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getCluster()

RelOptCluster org.apache.calcite.sql2rel.SqlToRelConverter.getCluster ( )
inline
Returns
the RelOptCluster in use.

Definition at line 341 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.cluster.

341  {
342  return cluster;
343  }

◆ getColumnMappings()

Set<RelColumnMapping> org.apache.calcite.sql2rel.SqlToRelConverter.getColumnMappings ( SqlOperator  op)
inlineprivate

Definition at line 2405 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertCollectionTable().

2405  {
2406  SqlReturnTypeInference rti = op.getReturnTypeInference();
2407  if (rti == null) {
2408  return null;
2409  }
2410  if (rti instanceof TableFunctionReturnTypeInference) {
2411  TableFunctionReturnTypeInference tfrti = (TableFunctionReturnTypeInference) rti;
2412  return tfrti.getColumnMappings();
2413  } else {
2414  return null;
2415  }
2416  }
+ Here is the caller graph for this function:

◆ getCorrelationUse()

CorrelationUse org.apache.calcite.sql2rel.SqlToRelConverter.getCorrelationUse ( Blackboard  bb,
final RelNode  r0 
)
inlineprivate

Definition at line 2505 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.DeferredLookup.bb, field(), org.apache.calcite.sql2rel.SqlToRelConverter.DeferredLookup.getFieldAccess(), org.apache.calcite.sql2rel.SqlToRelConverter.DeferredLookup.getOriginalRelName(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.mapRootRelToFieldProjection, org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root, and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.scope.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertWhere(), and org.apache.calcite.sql2rel.SqlToRelConverter.createJoin().

2505  {
2506  final Set<CorrelationId> correlatedVariables = RelOptUtil.getVariablesUsed(r0);
2507  if (correlatedVariables.isEmpty()) {
2508  return null;
2509  }
2510  final ImmutableBitSet.Builder requiredColumns = ImmutableBitSet.builder();
2511  final List<CorrelationId> correlNames = new ArrayList<>();
2512 
2513  // All correlations must refer the same namespace since correlation
2514  // produces exactly one correlation source.
2515  // The same source might be referenced by different variables since
2516  // DeferredLookups are not de-duplicated at create time.
2517  SqlValidatorNamespace prevNs = null;
2518 
2519  for (CorrelationId correlName : correlatedVariables) {
2520  DeferredLookup lookup = mapCorrelToDeferred.get(correlName);
2521  RexFieldAccess fieldAccess = lookup.getFieldAccess(correlName);
2522  String originalRelName = lookup.getOriginalRelName();
2523  String originalFieldName = fieldAccess.getField().getName();
2524 
2525  final SqlNameMatcher nameMatcher =
2526  bb.getValidator().getCatalogReader().nameMatcher();
2527  final SqlValidatorScope.ResolvedImpl resolved =
2528  new SqlValidatorScope.ResolvedImpl();
2529  lookup.bb.scope.resolve(
2530  ImmutableList.of(originalRelName), nameMatcher, false, resolved);
2531  assert resolved.count() == 1;
2532  final SqlValidatorScope.Resolve resolve = resolved.only();
2533  final SqlValidatorNamespace foundNs = resolve.namespace;
2534  final RelDataType rowType = resolve.rowType();
2535  final int childNamespaceIndex = resolve.path.steps().get(0).i;
2536  final SqlValidatorScope ancestorScope = resolve.scope;
2537  boolean correlInCurrentScope = bb.scope.isWithin(ancestorScope);
2538 
2539  if (!correlInCurrentScope) {
2540  continue;
2541  }
2542 
2543  if (prevNs == null) {
2544  prevNs = foundNs;
2545  } else {
2546  assert prevNs
2547  == foundNs : "All correlation variables should resolve"
2548  + " to the same namespace."
2549  + " Prev ns="
2550  + prevNs
2551  + ", new ns="
2552  + foundNs;
2553  }
2554 
2555  int namespaceOffset = 0;
2556  if (childNamespaceIndex > 0) {
2557  // If not the first child, need to figure out the width
2558  // of output types from all the preceding namespaces
2559  assert ancestorScope instanceof ListScope;
2560  List<SqlValidatorNamespace> children = ((ListScope) ancestorScope).getChildren();
2561 
2562  for (int i = 0; i < childNamespaceIndex; i++) {
2563  SqlValidatorNamespace child = children.get(i);
2564  namespaceOffset += child.getRowType().getFieldCount();
2565  }
2566  }
2567 
2568  RexFieldAccess topLevelFieldAccess = fieldAccess;
2569  while (topLevelFieldAccess.getReferenceExpr() instanceof RexFieldAccess) {
2570  topLevelFieldAccess = (RexFieldAccess) topLevelFieldAccess.getReferenceExpr();
2571  }
2572  final RelDataTypeField field = rowType.getFieldList().get(
2573  topLevelFieldAccess.getField().getIndex() - namespaceOffset);
2574  int pos = namespaceOffset + field.getIndex();
2575 
2576  assert field.getType() == topLevelFieldAccess.getField().getType();
2577 
2578  assert pos != -1;
2579 
2580  if (bb.mapRootRelToFieldProjection.containsKey(bb.root)) {
2581  // bb.root is an aggregate and only projects group by
2582  // keys.
2583  Map<Integer, Integer> exprProjection =
2584  bb.mapRootRelToFieldProjection.get(bb.root);
2585 
2586  // sub-query can reference group by keys projected from
2587  // the root of the outer relation.
2588  if (exprProjection.containsKey(pos)) {
2589  pos = exprProjection.get(pos);
2590  } else {
2591  // correl not grouped
2592  throw new AssertionError("Identifier '" + originalRelName + "."
2593  + originalFieldName + "' is not a group expr");
2594  }
2595  }
2596 
2597  requiredColumns.set(pos);
2598  correlNames.add(correlName);
2599  }
2600 
2601  if (correlNames.isEmpty()) {
2602  // None of the correlating variables originated in this scope.
2603  return null;
2604  }
2605 
2606  RelNode r = r0;
2607  if (correlNames.size() > 1) {
2608  // The same table was referenced more than once.
2609  // So we deduplicate.
2610  r = DeduplicateCorrelateVariables.go(
2611  rexBuilder, correlNames.get(0), Util.skip(correlNames), r0);
2612  // Add new node to leaves.
2613  leaves.put(r, r.getRowType().getFieldCount());
2614  }
2615  return new CorrelationUse(correlNames.get(0), requiredColumns.build(), r);
2616  }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
final Map< CorrelationId, DeferredLookup > mapCorrelToDeferred
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getDynamicParamCount()

int org.apache.calcite.sql2rel.SqlToRelConverter.getDynamicParamCount ( )
inline

Returns the number of dynamic parameters encountered during translation; this must only be called after convertQuery.

Returns
number of dynamic parameters

Definition at line 358 of file SqlToRelConverter.java.

358  {
359  return dynamicParamSqlNodes.size();
360  }
final List< SqlDynamicParam > dynamicParamSqlNodes

◆ getDynamicParamCountInExplain()

int org.apache.calcite.sql2rel.SqlToRelConverter.getDynamicParamCountInExplain ( boolean  increment)
inline

Returns the current count of the number of dynamic parameters in an EXPLAIN PLAN statement.

Parameters
incrementif true, increment the count
Returns
the current count before the optional increment

Definition at line 383 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.explainParamCount.

383  {
384  int retVal = explainParamCount;
385  if (increment) {
387  }
388  return retVal;
389  }

◆ getDynamicParamType()

RelDataType org.apache.calcite.sql2rel.SqlToRelConverter.getDynamicParamType ( int  index)
inline

Returns the type inferred for a dynamic parameter.

Parameters
index0-based index of dynamic parameter
Returns
inferred type, never null

Definition at line 368 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertDynamicParam().

368  {
369  SqlNode sqlNode = dynamicParamSqlNodes.get(index);
370  if (sqlNode == null) {
371  throw Util.needToImplement("dynamic param type inference");
372  }
373  return validator.getValidatedNodeType(sqlNode);
374  }
final List< SqlDynamicParam > dynamicParamSqlNodes
+ Here is the caller graph for this function:

◆ getInitializerFactory()

InitializerExpressionFactory org.apache.calcite.sql2rel.SqlToRelConverter.getInitializerFactory ( SqlValidatorTable  validatorTable)
inlineprivate

Definition at line 3530 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.unwrap().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertColumnList().

3531  {
3532  // We might unwrap a null instead of a InitializerExpressionFactory.
3533  final Table table = unwrap(validatorTable, Table.class);
3534  if (table != null) {
3535  InitializerExpressionFactory f = unwrap(table, InitializerExpressionFactory.class);
3536  if (f != null) {
3537  return f;
3538  }
3539  }
3540  return NullInitializerExpressionFactory.INSTANCE;
3541  }
static< T > T unwrap(Object o, Class< T > clazz)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getInSubqueryThreshold()

int org.apache.calcite.sql2rel.SqlToRelConverter.getInSubqueryThreshold ( )
inlineprotected

Gets the list size threshold under which convertInToOr is used. Lists of this size or greater will instead be converted to use a join against an inline table (org.apache.calcite.rel.logical.LogicalValues) rather than a predicate. A threshold of 0 forces usage of an inline table in all cases; a threshold of Integer.MAX_VALUE forces usage of OR in all cases

Returns
threshold, default DEFAULT_IN_SUB_QUERY_THRESHOLD

Definition at line 1501 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.config.

1501  {
1502  return config.getInSubQueryThreshold();
1503  }

◆ getMapConvertedNonCorrSubqs()

Map<SqlNode, RexNode> org.apache.calcite.sql2rel.SqlToRelConverter.getMapConvertedNonCorrSubqs ( )
inline
Returns
mapping of non-correlated sub-queries that have been converted to the constants that they evaluate to

Definition at line 395 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.mapConvertedNonCorrSubqs.

395  {
397  }
final Map< SqlNode, RexNode > mapConvertedNonCorrSubqs

◆ getRexBuilder()

RexBuilder org.apache.calcite.sql2rel.SqlToRelConverter.getRexBuilder ( )
inline

Returns the row-expression builder.

Definition at line 348 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.rexBuilder.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.lookupExp().

348  {
349  return rexBuilder;
350  }
+ Here is the caller graph for this function:

◆ getSystemFields()

List<RelDataTypeField> org.apache.calcite.sql2rel.SqlToRelConverter.getSystemFields ( )
inlineprotected

Returns a list of fields to be prefixed to each relational expression.

Returns
List of system fields

Definition at line 2665 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setRoot().

2665  {
2666  return Collections.emptyList();
2667  }
+ Here is the caller graph for this function:

◆ getTargetTable()

RelOptTable org.apache.calcite.sql2rel.SqlToRelConverter.getTargetTable ( SqlNode  call)
inlineprotected

Definition at line 3426 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.catalogReader.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.collectInsertTargets(), org.apache.calcite.sql2rel.SqlToRelConverter.convertColumnList(), org.apache.calcite.sql2rel.SqlToRelConverter.convertDelete(), org.apache.calcite.sql2rel.SqlToRelConverter.convertInsert(), org.apache.calcite.sql2rel.SqlToRelConverter.convertMerge(), and org.apache.calcite.sql2rel.SqlToRelConverter.convertUpdate().

3426  {
3427  final SqlValidatorNamespace targetNs = validator.getNamespace(call);
3428  if (targetNs.isWrapperFor(SqlValidatorImpl.DmlNamespace.class)) {
3429  final SqlValidatorImpl.DmlNamespace dmlNamespace =
3430  targetNs.unwrap(SqlValidatorImpl.DmlNamespace.class);
3431  return SqlValidatorUtil.getRelOptTable(dmlNamespace, catalogReader, null, null);
3432  }
3433  final SqlValidatorNamespace resolvedNamespace = targetNs.resolve();
3434  return SqlValidatorUtil.getRelOptTable(resolvedNamespace, catalogReader, null, null);
3435  }
+ Here is the caller graph for this function:

◆ isOrdered()

static boolean org.apache.calcite.sql2rel.SqlToRelConverter.isOrdered ( SqlNode  query)
inlinestatic

Definition at line 602 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertQuery().

602  {
603  switch (query.getKind()) {
604  case SELECT:
605  return ((SqlSelect) query).getOrderList() != null
606  && ((SqlSelect) query).getOrderList().size() > 0;
607  case WITH:
608  return isOrdered(((SqlWith) query).body);
609  case ORDER_BY:
610  return ((SqlOrderBy) query).orderList.size() > 0;
611  default:
612  return false;
613  }
614  }
+ Here is the caller graph for this function:

◆ isRowConstructor()

boolean org.apache.calcite.sql2rel.SqlToRelConverter.isRowConstructor ( SqlNode  node)
inlineprivate

Definition at line 1673 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertRowConstructor(), and org.apache.calcite.sql2rel.SqlToRelConverter.convertRowValues().

1673  {
1674  if (!(node.getKind() == SqlKind.ROW)) {
1675  return false;
1676  }
1677  SqlCall call = (SqlCall) node;
1678  return call.getOperator().getName().equalsIgnoreCase("row");
1679  }
+ Here is the caller graph for this function:

◆ isStream()

static boolean org.apache.calcite.sql2rel.SqlToRelConverter.isStream ( SqlNode  query)
inlinestaticprivate

Definition at line 597 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertQuery().

597  {
598  return query instanceof SqlSelect
599  && ((SqlSelect) query).isKeywordPresent(SqlSelectKeyword.STREAM);
600  }
+ Here is the caller graph for this function:

◆ isSubQueryNonCorrelated()

boolean org.apache.calcite.sql2rel.SqlToRelConverter.isSubQueryNonCorrelated ( RelNode  subq,
Blackboard  bb 
)
inlineprivate

Determines whether a sub-query is non-correlated. Note that a non-correlated sub-query can contain correlated references, provided those references do not reference select statements that are parents of the sub-query.

Parameters
subqthe sub-query
bbblackboard used while converting the sub-query, i.e., the blackboard of the parent query of this sub-query
Returns
true if the sub-query is non-correlated

Definition at line 2628 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.DeferredLookup.bb, org.apache.calcite.sql2rel.SqlToRelConverter.DeferredLookup.getOriginalRelName(), and org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.scope.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertNonCorrelatedSubQuery().

2628  {
2629  Set<CorrelationId> correlatedVariables = RelOptUtil.getVariablesUsed(subq);
2630  for (CorrelationId correlName : correlatedVariables) {
2631  DeferredLookup lookup = mapCorrelToDeferred.get(correlName);
2632  String originalRelName = lookup.getOriginalRelName();
2633 
2634  final SqlNameMatcher nameMatcher =
2635  lookup.bb.scope.getValidator().getCatalogReader().nameMatcher();
2636  final SqlValidatorScope.ResolvedImpl resolved =
2637  new SqlValidatorScope.ResolvedImpl();
2638  lookup.bb.scope.resolve(
2639  ImmutableList.of(originalRelName), nameMatcher, false, resolved);
2640 
2641  SqlValidatorScope ancestorScope = resolved.only().scope;
2642 
2643  // If the correlated reference is in a scope that's "above" the
2644  // sub-query, then this is a correlated sub-query.
2645  SqlValidatorScope parentScope = bb.scope;
2646  do {
2647  if (ancestorScope == parentScope) {
2648  return false;
2649  }
2650  if (parentScope instanceof DelegatingScope) {
2651  parentScope = ((DelegatingScope) parentScope).getParent();
2652  } else {
2653  break;
2654  }
2655  } while (parentScope != null);
2656  }
2657  return true;
2658  }
final Map< CorrelationId, DeferredLookup > mapCorrelToDeferred
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isTrimUnusedFields()

boolean org.apache.calcite.sql2rel.SqlToRelConverter.isTrimUnusedFields ( )
inline

Returns whether to trim unused fields as part of the conversion process.

Returns
Whether to trim unused fields

Definition at line 3216 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.config, and org.apache.calcite.sql2rel.SqlToRelConverter.isTrimUnusedFields().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.NoOpSubQueryConverter.convertSubQuery(), org.apache.calcite.sql2rel.SqlToRelConverter.isTrimUnusedFields(), and org.apache.calcite.sql2rel.SqlToRelConverter.trimUnusedFields().

3216  {
3217  return config.isTrimUnusedFields();
3218  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ negate()

SqlQuantifyOperator org.apache.calcite.sql2rel.SqlToRelConverter.negate ( SqlQuantifyOperator  operator)
inlineprivate

Definition at line 4790 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.lookupExp().

4790  {
4791  assert operator.kind == SqlKind.ALL;
4792  return SqlStdOperatorTable.some(operator.comparisonKind.negateNullSafe());
4793  }
+ Here is the caller graph for this function:

◆ newFieldTrimmer()

RelFieldTrimmer org.apache.calcite.sql2rel.SqlToRelConverter.newFieldTrimmer ( )
inlineprotected

Creates a RelFieldTrimmer.

Returns
Field trimmer

Definition at line 540 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.trimUnusedFields().

540  {
541  return new RelFieldTrimmer(validator, relBuilder);
542  }
+ Here is the caller graph for this function:

◆ pushDownNotForIn()

static SqlNode org.apache.calcite.sql2rel.SqlToRelConverter.pushDownNotForIn ( SqlValidatorScope  scope,
SqlNode  sqlNode 
)
inlinestaticprivate

Push down all the NOT logical operators into any IN/NOT IN operators.

Parameters
scopeScope where
sqlNode
occurs
sqlNodethe root node from which to look for NOT operators
Returns
the transformed SqlNode representation with NOT pushed down.

Definition at line 868 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.containsInOperator(), and org.apache.calcite.sql2rel.SqlToRelConverter.reg().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertWhere(), and org.apache.calcite.sql2rel.SqlToRelConverter.createAggImpl().

868  {
869  if (!(sqlNode instanceof SqlCall) || !containsInOperator(sqlNode)) {
870  return sqlNode;
871  }
872  final SqlCall sqlCall = (SqlCall) sqlNode;
873  switch (sqlCall.getKind()) {
874  case AND:
875  case OR:
876  final List<SqlNode> operands = new ArrayList<>();
877  for (SqlNode operand : sqlCall.getOperandList()) {
878  operands.add(pushDownNotForIn(scope, operand));
879  }
880  final SqlCall newCall =
881  sqlCall.getOperator().createCall(sqlCall.getParserPosition(), operands);
882  return reg(scope, newCall);
883 
884  case NOT:
885  assert sqlCall.operand(0) instanceof SqlCall;
886  final SqlCall call = sqlCall.operand(0);
887  switch (sqlCall.operand(0).getKind()) {
888  case CASE:
889  final SqlCase caseNode = (SqlCase) call;
890  final SqlNodeList thenOperands = new SqlNodeList(SqlParserPos.ZERO);
891 
892  for (SqlNode thenOperand : caseNode.getThenOperands()) {
893  final SqlCall not =
894  SqlStdOperatorTable.NOT.createCall(SqlParserPos.ZERO, thenOperand);
895  thenOperands.add(pushDownNotForIn(scope, reg(scope, not)));
896  }
897  SqlNode elseOperand = caseNode.getElseOperand();
898  if (!SqlUtil.isNull(elseOperand)) {
899  // "not(unknown)" is "unknown", so no need to simplify
900  final SqlCall not =
901  SqlStdOperatorTable.NOT.createCall(SqlParserPos.ZERO, elseOperand);
902  elseOperand = pushDownNotForIn(scope, reg(scope, not));
903  }
904 
905  return reg(scope,
906  SqlStdOperatorTable.CASE.createCall(SqlParserPos.ZERO,
907  caseNode.getValueOperand(),
908  caseNode.getWhenOperands(),
909  thenOperands,
910  elseOperand));
911 
912  case AND:
913  final List<SqlNode> orOperands = new ArrayList<>();
914  for (SqlNode operand : call.getOperandList()) {
915  orOperands.add(pushDownNotForIn(scope,
916  reg(scope,
917  SqlStdOperatorTable.NOT.createCall(
918  SqlParserPos.ZERO, operand))));
919  }
920  return reg(scope,
921  SqlStdOperatorTable.OR.createCall(SqlParserPos.ZERO, orOperands));
922 
923  case OR:
924  final List<SqlNode> andOperands = new ArrayList<>();
925  for (SqlNode operand : call.getOperandList()) {
926  andOperands.add(pushDownNotForIn(scope,
927  reg(scope,
928  SqlStdOperatorTable.NOT.createCall(
929  SqlParserPos.ZERO, operand))));
930  }
931  return reg(scope,
932  SqlStdOperatorTable.AND.createCall(SqlParserPos.ZERO, andOperands));
933 
934  case NOT:
935  assert call.operandCount() == 1;
936  return pushDownNotForIn(scope, call.operand(0));
937 
938  case NOT_IN:
939  return reg(scope,
940  SqlStdOperatorTable.IN.createCall(
941  SqlParserPos.ZERO, call.getOperandList()));
942 
943  case IN:
944  return reg(scope,
945  SqlStdOperatorTable.NOT_IN.createCall(
946  SqlParserPos.ZERO, call.getOperandList()));
947  }
948  }
949  return sqlNode;
950  }
static SqlNode pushDownNotForIn(SqlValidatorScope scope, SqlNode sqlNode)
static SqlNode reg(SqlValidatorScope scope, SqlNode e)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reg()

static SqlNode org.apache.calcite.sql2rel.SqlToRelConverter.reg ( SqlValidatorScope  scope,
SqlNode  e 
)
inlinestaticprivate

Registers with the validator a SqlNode that has been created during the Sql-to-Rel process.

Definition at line 956 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.pushDownNotForIn().

956  {
957  scope.getValidator().deriveType(scope, e);
958  return e;
959  }
+ Here is the caller graph for this function:

◆ replaceSubQueries()

void org.apache.calcite.sql2rel.SqlToRelConverter.replaceSubQueries ( final Blackboard  bb,
final SqlNode  expr,
RelOptUtil.Logic  logic 
)
inlineprivate

Definition at line 998 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.findSubQueries(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.subQueryList, and org.apache.calcite.sql2rel.SqlToRelConverter.substituteSubQuery().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertCollectionTable(), org.apache.calcite.sql2rel.SqlToRelConverter.convertJoinCondition(), org.apache.calcite.sql2rel.SqlToRelConverter.convertMatchRecognize(), org.apache.calcite.sql2rel.SqlToRelConverter.convertSelectList(), org.apache.calcite.sql2rel.SqlToRelConverter.convertUnnest(), org.apache.calcite.sql2rel.SqlToRelConverter.convertUpdate(), org.apache.calcite.sql2rel.SqlToRelConverter.convertValuesImpl(), org.apache.calcite.sql2rel.SqlToRelConverter.convertWhere(), and org.apache.calcite.sql2rel.SqlToRelConverter.createAggImpl().

999  {
1000  findSubQueries(bb, expr, logic, false);
1001  for (SubQuery node : bb.subQueryList) {
1002  substituteSubQuery(bb, node);
1003  }
1004  }
void substituteSubQuery(Blackboard bb, SubQuery subQuery)
void findSubQueries(Blackboard bb, SqlNode node, RelOptUtil.Logic logic, boolean registerOnlyScalarSubQueries)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ requiredCollation()

RelCollation org.apache.calcite.sql2rel.SqlToRelConverter.requiredCollation ( RelNode  r)
inlineprivate

Definition at line 616 of file SqlToRelConverter.java.

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.convertQuery().

616  {
617  if (r instanceof Sort) {
618  return ((Sort) r).collation;
619  }
620  if (r instanceof Project) {
621  return requiredCollation(((Project) r).getInput());
622  }
623  if (r instanceof Delta) {
624  return requiredCollation(((Delta) r).getInput());
625  }
626  throw new AssertionError();
627  }
+ Here is the caller graph for this function:

◆ rewriteAggregateWithGroupId()

RelNode org.apache.calcite.sql2rel.SqlToRelConverter.rewriteAggregateWithGroupId ( Blackboard  bb,
AggregatingSelectScope.Resolved  r,
AggConverter  converter 
)
inlineprivate

The

GROUP_ID()

function is used to distinguish duplicate groups. However, as Aggregate normalizes group sets to canonical form (i.e., flatten, sorting, redundancy removal), this information is lost in RelNode. Therefore, it is impossible to implement the function in runtime.

To fill this gap, an aggregation query that contains

GROUP_ID()

function will generally be rewritten into UNION when converting to RelNode.

Also see the discussion in JIRA [CALCITE-1824] GROUP_ID returns wrong result.

Definition at line 2952 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.createAggregate().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.createAggImpl().

2953  {
2954  final List<AggregateCall> aggregateCalls = converter.getAggCalls();
2955  final ImmutableBitSet groupSet = r.groupSet;
2956  final Map<ImmutableBitSet, Integer> groupSetCount = r.groupSetCount;
2957 
2958  final List<String> fieldNamesIfNoRewrite =
2959  createAggregate(bb, groupSet, r.groupSets, aggregateCalls)
2960  .getRowType()
2961  .getFieldNames();
2962 
2963  // If n duplicates exist for a particular grouping, the {@code GROUP_ID()}
2964  // function produces values in the range 0 to n-1. For each value,
2965  // we need to figure out the corresponding group sets.
2966  //
2967  // For example, "... GROUPING SETS (a, a, b, c, c, c, c)"
2968  // (i) The max value of the GROUP_ID() function returns is 3
2969  // (ii) GROUPING SETS (a, b, c) produces value 0,
2970  // GROUPING SETS (a, c) produces value 1,
2971  // GROUPING SETS (c) produces value 2
2972  // GROUPING SETS (c) produces value 3
2973  final Map<Integer, Set<ImmutableBitSet>> groupIdToGroupSets = new HashMap<>();
2974  int maxGroupId = 0;
2975  for (Map.Entry<ImmutableBitSet, Integer> entry : groupSetCount.entrySet()) {
2976  int groupId = entry.getValue() - 1;
2977  if (groupId > maxGroupId) {
2978  maxGroupId = groupId;
2979  }
2980  for (int i = 0; i <= groupId; i++) {
2981  groupIdToGroupSets
2982  .computeIfAbsent(i, k -> Sets.newTreeSet(ImmutableBitSet.COMPARATOR))
2983  .add(entry.getKey());
2984  }
2985  }
2986 
2987  // AggregateCall list without GROUP_ID function
2988  final List<AggregateCall> aggregateCallsWithoutGroupId = new ArrayList<>();
2989  for (AggregateCall aggregateCall : aggregateCalls) {
2990  if (aggregateCall.getAggregation().kind != SqlKind.GROUP_ID) {
2991  aggregateCallsWithoutGroupId.add(aggregateCall);
2992  }
2993  }
2994  final List<RelNode> projects = new ArrayList<>();
2995  // For each group id value , we first construct an Aggregate without
2996  // GROUP_ID() function call, and then create a Project node on top of it.
2997  // The Project adds literal value for group id in right position.
2998  for (int groupId = 0; groupId <= maxGroupId; groupId++) {
2999  // Create the Aggregate node without GROUP_ID() call
3000  final ImmutableList<ImmutableBitSet> groupSets =
3001  ImmutableList.copyOf(groupIdToGroupSets.get(groupId));
3002  final RelNode aggregate =
3003  createAggregate(bb, groupSet, groupSets, aggregateCallsWithoutGroupId);
3004 
3005  // RexLiteral for each GROUP_ID, note the type should be BIGINT
3006  final RelDataType groupIdType = typeFactory.createSqlType(SqlTypeName.BIGINT);
3007  final RexNode groupIdLiteral =
3008  rexBuilder.makeExactLiteral(BigDecimal.valueOf(groupId), groupIdType);
3009 
3010  relBuilder.push(aggregate);
3011  final List<RexNode> selectList = new ArrayList<>();
3012  final int groupExprLength = r.groupExprList.size();
3013  // Project fields in group by expressions
3014  for (int i = 0; i < groupExprLength; i++) {
3015  selectList.add(relBuilder.field(i));
3016  }
3017  // Project fields in aggregate calls
3018  int groupIdCount = 0;
3019  for (int i = 0; i < aggregateCalls.size(); i++) {
3020  if (aggregateCalls.get(i).getAggregation().kind == SqlKind.GROUP_ID) {
3021  selectList.add(groupIdLiteral);
3022  groupIdCount++;
3023  } else {
3024  int ordinal = groupExprLength + i - groupIdCount;
3025  selectList.add(relBuilder.field(ordinal));
3026  }
3027  }
3028  final RelNode project =
3029  relBuilder.project(selectList, fieldNamesIfNoRewrite).build();
3030  projects.add(project);
3031  }
3032  // Skip to create Union when there is only one child, i.e., no duplicate group
3033  // set.
3034  if (projects.size() == 1) {
3035  return projects.get(0);
3036  }
3037  return LogicalUnion.create(projects, true);
3038  }
RelNode createAggregate(Blackboard bb, ImmutableBitSet groupSet, ImmutableList< ImmutableBitSet > groupSets, List< AggregateCall > aggCalls)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setDynamicParamCountInExplain()

void org.apache.calcite.sql2rel.SqlToRelConverter.setDynamicParamCountInExplain ( int  explainParamCount)
inline

Sets the number of dynamic parameters in the current EXPLAIN PLAN statement.

Parameters
explainParamCountnumber of dynamic parameters in the statement

Definition at line 426 of file SqlToRelConverter.java.

References org.apache.calcite.sql2rel.SqlToRelConverter.config, and org.apache.calcite.sql2rel.SqlToRelConverter.explainParamCount.

426  {
427  assert config.isExplain();
429  }

◆ setSubQueryConverter()

void org.apache.calcite.sql2rel.SqlToRelConverter.setSubQueryConverter ( SubQueryConverter  converter)
inline

Sets a new SubQueryConverter. To have any effect, this must be called before any convert method.

Parameters
converternew SubQueryConverter

Definition at line 417 of file SqlToRelConverter.java.

417  {
418  subQueryConverter = converter;
419  }

◆ substituteSubQuery()

void org.apache.calcite.sql2rel.SqlToRelConverter.substituteSubQuery ( Blackboard  bb,
SubQuery  subQuery 
)
inlineprivate

Definition at line 1006 of file SqlToRelConverter.java.

References run_benchmark_import.args, org.apache.calcite.sql2rel.SqlToRelConverter.config, org.apache.calcite.sql2rel.SqlToRelConverter.containsNullLiteral(), org.apache.calcite.sql2rel.SqlToRelConverter.convertCursor(), org.apache.calcite.sql2rel.SqlToRelConverter.convertExists(), org.apache.calcite.sql2rel.SqlToRelConverter.convertInToOr(), org.apache.calcite.sql2rel.SqlToRelConverter.convertMultisets(), org.apache.calcite.sql2rel.SqlToRelConverter.convertNonCorrelatedSubQuery(), org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryOrInList(), org.apache.calcite.sql2rel.SqlToRelConverter.convertToSingleValueSubq(), org.apache.calcite.sql2rel.SqlToRelConverter.createBlackboard(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.cursors, Double, org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.getTopNode(), join(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.register(), org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.root, org.apache.calcite.sql2rel.SqlToRelConverter.Blackboard.setRoot(), and org.apache.calcite.sql2rel.SqlToRelConverter.translateIn().

Referenced by org.apache.calcite.sql2rel.SqlToRelConverter.replaceSubQueries().

1006  {
1007  final RexNode expr = subQuery.expr;
1008  if (expr != null) {
1009  // Already done.
1010  return;
1011  }
1012 
1013  final SqlBasicCall call;
1014  final RelNode rel;
1015  final SqlNode query;
1016  final RelOptUtil.Exists converted;
1017 
1018  boolean isExpand = config.getExpandPredicate().test(bb.getTopNode(), subQuery.node);
1019 
1020  switch (subQuery.node.getKind()) {
1021  case CURSOR:
1022  convertCursor(bb, subQuery);
1023  return;
1024 
1025  case MULTISET_QUERY_CONSTRUCTOR:
1026  case MULTISET_VALUE_CONSTRUCTOR:
1027  case ARRAY_QUERY_CONSTRUCTOR:
1028  rel = convertMultisets(ImmutableList.of(subQuery.node), bb);
1029  subQuery.expr = bb.register(rel, JoinRelType.INNER);
1030  return;
1031 
1032  case IN:
1033  case NOT_IN:
1034  case SOME:
1035  case ALL:
1036  call = (SqlBasicCall) subQuery.node;
1037  query = call.operand(1);
1038  if (!isExpand && !(query instanceof SqlNodeList)) {
1039  return;
1040  }
1041  final SqlNode leftKeyNode = call.operand(0);
1042 
1043  final List<RexNode> leftKeys;
1044  switch (leftKeyNode.getKind()) {
1045  case ROW:
1046  leftKeys = new ArrayList<>();
1047  for (SqlNode sqlExpr : ((SqlBasicCall) leftKeyNode).getOperandList()) {
1048  leftKeys.add(bb.convertExpression(sqlExpr));
1049  }
1050  break;
1051  default:
1052  leftKeys = ImmutableList.of(bb.convertExpression(leftKeyNode));
1053  }
1054 
1055  if (query instanceof SqlNodeList) {
1056  SqlNodeList valueList = (SqlNodeList) query;
1057  if (!containsNullLiteral(valueList)
1058  && valueList.size() < config.getInSubQueryThreshold()) {
1059  // We're under the threshold, so convert to OR.
1060  subQuery.expr = convertInToOr(
1061  bb, leftKeys, valueList, (SqlInOperator) call.getOperator());
1062  return;
1063  }
1064 
1065  // Otherwise, let convertExists translate
1066  // values list into an inline table for the
1067  // reference to Q below.
1068  }
1069 
1070  // Project out the search columns from the left side
1071 
1072  // Q1:
1073  // "select from emp where emp.deptno in (select col1 from T)"
1074  //
1075  // is converted to
1076  //
1077  // "select from
1078  // emp inner join (select distinct col1 from T)) q
1079  // on emp.deptno = q.col1
1080  //
1081  // Q2:
1082  // "select from emp where emp.deptno not in (Q)"
1083  //
1084  // is converted to
1085  //
1086  // "select from
1087  // emp left outer join (select distinct col1, TRUE from T) q
1088  // on emp.deptno = q.col1
1089  // where emp.deptno <> null
1090  // and q.indicator <> TRUE"
1091  //
1092  // Note: Sub-query can be used as SqlUpdate#condition like below:
1093  //
1094  // UPDATE emp
1095  // SET empno = 1 WHERE emp.empno IN (
1096  // SELECT emp.empno FROM emp WHERE emp.empno = 2)
1097  //
1098  // In such case, when converting SqlUpdate#condition, bb.root is null
1099  // and it makes no sense to do the sub-query substitution.
1100  if (bb.root == null) {
1101  return;
1102  }
1103  final RelDataType targetRowType = SqlTypeUtil.promoteToRowType(
1104  typeFactory, validator.getValidatedNodeType(leftKeyNode), null);
1105  final boolean notIn = call.getOperator().kind == SqlKind.NOT_IN;
1106  converted = convertExists(
1107  query, RelOptUtil.SubQueryType.IN, subQuery.logic, notIn, targetRowType);
1108  if (converted.indicator) {
1109  // Generate
1110  // emp CROSS JOIN (SELECT COUNT(*) AS c,
1111  // COUNT(deptno) AS ck FROM dept)
1112  final RelDataType longType = typeFactory.createSqlType(SqlTypeName.BIGINT);
1113