imay commented on a change in pull request #1592: Broker load supports function
URL: https://github.com/apache/incubator-doris/pull/1592#discussion_r311382461
 
 

 ##########
 File path: fe/src/main/java/org/apache/doris/planner/BrokerScanNode.java
 ##########
 @@ -339,75 +239,189 @@ private void initParams(ParamCreateContext context) 
throws AnalysisException, Us
         }
 
         params.setProperties(brokerDesc.getProperties());
+        initColumns(context);
+    }
 
-        // We must create a new map here, because we will change this map 
later.
-        // But fileGroup will be persisted later, so we keep it unchanged.
-        if (fileGroup.getExprColumnMap() != null) {
-            context.exprMap = Maps.newHashMap(fileGroup.getExprColumnMap());
-        } else {
-            context.exprMap = null;
-        }
-        parseExprMap(context.exprMap);
+    private void initColumns(ParamCreateContext context) throws UserException {
+        // This tuple descriptor is used for origin file
+        TupleDescriptor srcTupleDesc = 
analyzer.getDescTbl().createTupleDescriptor();
+        context.tupleDescriptor = srcTupleDesc;
+        Map<String, SlotDescriptor> slotDescByName = Maps.newHashMap();
+        context.slotDescByName = slotDescByName;
 
-        // Generate expr
-        List<String> fileFieldNames = fileGroup.getFileFieldNames();
-        if (fileFieldNames == null) {
-            fileFieldNames = Lists.newArrayList();
+        TBrokerScanRangeParams params = context.params;
+        // there are no columns transform
+        List<ImportColumnDesc> originColumnNameToExprList = 
context.fileGroup.getColumnExprList();
+        if (originColumnNameToExprList == null || 
originColumnNameToExprList.isEmpty()) {
             for (Column column : targetTable.getBaseSchema()) {
-                fileFieldNames.add(column.getName());
+                SlotDescriptor slotDesc = 
analyzer.getDescTbl().addSlotDescriptor(srcTupleDesc);
+                slotDesc.setType(ScalarType.createType(PrimitiveType.VARCHAR));
+                slotDesc.setIsMaterialized(true);
+                // same as ISSUE A
+                slotDesc.setIsNullable(true);
+                slotDescByName.put(column.getName(), slotDesc);
+                params.addToSrc_slot_ids(slotDesc.getId().asInt());
             }
-        } else {
-            // change fileFiledName to real column name(case match)
-            fileFieldNames = fileFieldNames.stream().map(
-                    f -> targetTable.getColumn(f) == null ? f : 
targetTable.getColumn(f).getName()).collect(
-                            Collectors.toList());
+            params.setSrc_tuple_id(srcTupleDesc.getId().asInt());
+            return;
         }
 
-        // This tuple descriptor is used for file of
-        TupleDescriptor srcTupleDesc = 
analyzer.getDescTbl().createTupleDescriptor();
-        context.tupleDescriptor = srcTupleDesc;
-
-        Map<String, SlotDescriptor> slotDescByName = Maps.newHashMap();
-        context.slotDescByName = slotDescByName;
-        for (String fieldName : fileFieldNames) {
-            SlotDescriptor slotDesc = 
analyzer.getDescTbl().addSlotDescriptor(srcTupleDesc);
-            slotDesc.setType(ScalarType.createType(PrimitiveType.VARCHAR));
-            slotDesc.setIsMaterialized(true);
-            slotDesc.setIsNullable(false);
-            slotDesc.setColumn(new Column(fieldName, PrimitiveType.VARCHAR));
-            slotDescByName.put(fieldName, slotDesc);
+        // there are columns expr which belong to load
+        Map<String, Expr> columnNameToExpr = Maps.newHashMap();
+        context.exprMap = columnNameToExpr;
+        for (ImportColumnDesc originColumnNameToExpr : 
originColumnNameToExprList) {
+            // make column name case match with real column name
+            String columnName = originColumnNameToExpr.getColumnName();
+            Expr columnExpr = originColumnNameToExpr.getExpr();
+            String realColName = targetTable.getColumn(columnName) == null ? 
columnName
+                    : targetTable.getColumn(columnName).getName();
+            if (columnExpr != null) {
+                columnExpr = transformHadoopFunctionExpr(columnName, 
columnExpr);
+                columnNameToExpr.put(realColName, columnExpr);
+            } else {
+                SlotDescriptor slotDesc = 
analyzer.getDescTbl().addSlotDescriptor(srcTupleDesc);
+                slotDesc.setType(ScalarType.createType(PrimitiveType.VARCHAR));
+                slotDesc.setIsMaterialized(true);
+                // ISSUE A: src slot should be nullable even if the column is 
not nullable.
+                // because src slot is what we read from file, not represent 
to real column value.
+                // If column is not nullable, error will be thrown when 
filling the dest slot,
+                // which is not nullable
+                slotDesc.setIsNullable(true);
+                params.addToSrc_slot_ids(slotDesc.getId().asInt());
+                slotDescByName.put(realColName, slotDesc);
+            }
+        }
+        // analyze all exprs
+        for (Map.Entry<String, Expr> entry : columnNameToExpr.entrySet()) {
+            ExprSubstitutionMap smap = new ExprSubstitutionMap();
+            List<SlotRef> slots = Lists.newArrayList();
+            entry.getValue().collect(SlotRef.class, slots);
+            for (SlotRef slot : slots) {
+                SlotDescriptor slotDesc = 
slotDescByName.get(slot.getColumnName());
+                if (slotDesc == null) {
+                    throw new UserException("unknown reference column, 
column=" + entry.getKey()
+                                                    + ", reference=" + 
slot.getColumnName());
+                }
+                smap.getLhs().add(slot);
+                smap.getRhs().add(new SlotRef(slotDesc));
+            }
+            Expr expr = entry.getValue().clone(smap);
+            expr.analyze(analyzer);
+
+            // check if contain aggregation
+            List<FunctionCallExpr> funcs = Lists.newArrayList();
+            expr.collect(FunctionCallExpr.class, funcs);
+            for (FunctionCallExpr fn : funcs) {
+                if (fn.isAggregateFunction()) {
+                    throw new AnalysisException("Don't support aggregation 
function in load expression");
+                }
+            }
 
-            params.addToSrc_slot_ids(slotDesc.getId().asInt());
+            columnNameToExpr.put(entry.getKey(), expr);
         }
         params.setSrc_tuple_id(srcTupleDesc.getId().asInt());
+
     }
 
-    private void finalizeParams(ParamCreateContext context) throws 
UserException, AnalysisException {
-        Map<String, SlotDescriptor> slotDescByName = context.slotDescByName;
-        Map<String, Expr> exprMap = context.exprMap;
-        Map<Integer, Integer> destSidToSrcSidWithoutTrans = Maps.newHashMap();
-        // Analyze expr map
-        if (exprMap != null) {
-            for (Map.Entry<String, Expr> entry : exprMap.entrySet()) {
-                ExprSubstitutionMap smap = new ExprSubstitutionMap();
-
-                List<SlotRef> slots = Lists.newArrayList();
-                entry.getValue().collect(SlotRef.class, slots);
-
-                for (SlotRef slot : slots) {
-                    SlotDescriptor slotDesc = 
slotDescByName.get(slot.getColumnName());
-                    if (slotDesc == null) {
-                        throw new UserException("Unknown slot");
+    private Expr transformHadoopFunctionExpr(String columnName, Expr 
originExpr) throws UserException {
 
 Review comment:
   should add comment for this function.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to